28 unsigned int lowBlock, highBlock, midBlock;
29 if (timeOffset <= buffer->lookup[0].m_timeOffset) {
38 lowBlock = midBlock = (timeOffset*highBlock)/(buffer->m_lastTimestamp-buffer->m_firstTimestamp);
42 if (timeOffset <= buffer->lookup[lowBlock].m_timeOffset) {
48 if (midBlock < highBlock)
50 if (timeOffset <= buffer->lookup[midBlock].m_timeOffset) {
58 midBlock = (lowBlock+highBlock)/2;
59 if (midBlock == lowBlock) {
62 }
else if (timeOffset <= buffer->lookup[midBlock].m_timeOffset) {
68 assert (lowBlock != highBlock);
69 *retBlock = highBlock;
110 for (buffer=
m_firstBuffer; buffer; buffer = buffer->m_next) {
111 if (buffer->m_firstFreePositionW == 0)
114 if (timestamp < buffer->m_firstTimestamp) {
120 unsigned short timeOffset = (
unsigned short)(timestamp-buffer->m_firstTimestamp);
121 unsigned int highBlock;
122 item =
_findBlock(buffer, timeOffset, &highBlock);
126 while (item<=limit && item->m_timeOffset < timeOffset )
145 for (prevBuffer=
NULL, buffer=
m_firstBuffer; buffer; prevBuffer = buffer, buffer = buffer->m_next) {
146 if (buffer->m_firstFreePositionW == 0)
149 if (timestamp <= buffer->m_firstTimestamp) {
150 if (prevBuffer ==
NULL) {
156 *rBuffer = prevBuffer;
161 unsigned short timeOffset = (
unsigned short)(timestamp-buffer->m_firstTimestamp);
162 unsigned int highBlock;
163 item =
_findBlock(buffer, timeOffset, &highBlock);
168 while (item<=limit && item->m_timeOffset < timeOffset) {
172 assert(item<=limit && prevItem!=
NULL);
179 if (prevBuffer ==
NULL) {
185 *rBuffer = prevBuffer;
204 CacheMap::iterator it = m_cache.find(device);
209 if (maxItemSize > 0x3FFF0)
212 if (it == m_cache.end()) {
217 if (!m_cache.insert(CacheMap::value_type(device,entry)).second) {
226 if (channel->m_busy && !strcmp(name, channel->m_name)) {
235 if (!channel->m_busy)
255 unsigned int bufSize = 1630*(maxItemSize+4);
258 if (bufSize < maxItemSize+16)
259 bufSize = maxItemSize+16;
260 bufSize = (bufSize + 3) & ~0x3;
267 if (blockSize < maxItemSize+12)
268 blockSize = maxItemSize+12;
271 unsigned int pwr2Size = blockSize;
272 while ((m = (pwr2Size & (pwr2Size-1))) != 0)
274 blockSize = (pwr2Size < blockSize) ? pwr2Size<<1 : pwr2Size;
277 channel->m_blockSizeW = blockSize;
278 channel->m_bufferSizeW = bufSize>>2;
279 channel->m_firstBuffer =
NULL;
280 channel->m_lastBuffer =
NULL;
282 channel->initItem =
NULL;
283 channel->m_maxItemSizeB = maxItemSize;
284 strncpy(channel->m_name, name,
sizeof(channel->m_name));
285 channel->m_name[
sizeof(channel->m_name)-1] = 0;
286 channel->m_positionToOffsetMaskW = (blockSize-1);
287 for (m=0; blockSize!=1; m++, blockSize>>=1);
288 channel->m_positionToBlockShiftW = m;
326 CacheMap::iterator it = (device) ? m_cache.find(device) : m_cache.begin();
331 unsigned int positionW, block;
333 while (it != m_cache.end()) {
335 for (
unsigned int ch=0; ch<entry->
m_count; ch++) {
337 if (channel->m_busy) {
338 item = channel->findItemOrLater(timestamp, &buffer);
345 while ((nextBuffer = buffer->m_next) !=
NULL) {
346 buffer->m_next = nextBuffer->m_next;
350 if (positionW == 0) {
353 nextBuffer = channel->m_firstBuffer;
355 while (nextBuffer != buffer) {
356 prevBuffer = nextBuffer;
357 nextBuffer = nextBuffer->m_next;
365 channel->m_firstBuffer =
NULL;
368 block = positionW>>channel->m_positionToBlockShiftW;
381 assert(nextItem==item);
384 buffer->m_firstFreePositionW = positionW;
385 buffer->m_lastTimestamp = buffer->m_firstTimestamp + prevItem->
m_timeOffset;
386 block = buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
387 buffer->lookup[block].m_offsetW = buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
388 buffer->lookup[block].m_timeOffset = prevItem->
m_timeOffset;
391 channel->m_lastBuffer = buffer;
393 channel->m_lastTimestamp = buffer->m_lastTimestamp;
394 channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
406void *
Cache::addCacheItem(
const void *device,
int id,
unsigned int timestamp,
void *data,
unsigned int length)
408 CacheMap::iterator it = m_cache.find(device);
413 unsigned int positionW, sizeW, block;
415 if (it == m_cache.end()) {
423 if (length > channel->m_maxItemSizeB)
425 if (timestamp == 0) {
435 channel->initItem = item;
437 if (!channel->m_lastBuffer) {
440 if ((buffer = channel->m_firstBuffer) ==
NULL) {
441 buffer = channel->allocBuffer();
442 channel->m_firstBuffer = buffer;
444 }
else if (timestamp > channel->m_lastTimestamp) {
446 buffer = channel->m_lastBuffer;
447 positionW = buffer->m_firstFreePositionW;
448 }
else if (timestamp == channel->m_lastTimestamp) {
450 buffer = channel->m_lastBuffer;
451 positionW = channel->m_lastItemPositionW;
456 item = channel->findItemOrLater(timestamp, &buffer);
462 while ((
next = buffer->m_next) !=
NULL) {
463 buffer->m_next =
next->m_next;
475 if ((positionW+sizeW > channel->m_bufferSizeW) ||
476 (positionW > 0 && timestamp >= buffer->m_firstTimestamp+0x10000)) {
479 if (positionW != buffer->m_firstFreePositionW) {
483 block = positionW>>channel->m_positionToBlockShiftW;
495 previousItem = nextItem;
497 assert(nextItem==item);
500 buffer->m_firstFreePositionW = positionW;
501 buffer->m_lastTimestamp = buffer->m_firstTimestamp + previousItem->
m_timeOffset;
502 block = buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
503 buffer->lookup[block].m_offsetW = buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
504 buffer->lookup[block].m_timeOffset = previousItem->
m_timeOffset;
506 channel->m_lastBuffer = buffer;
507 channel->m_lastTimestamp = buffer->m_lastTimestamp;
508 channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
511 buffer->m_next = channel->allocBuffer();
512 if (buffer->m_next ==
NULL)
514 buffer = buffer->m_next;
521 if (positionW == 0) {
523 buffer->m_firstTimestamp = timestamp;
525 item->
m_timeOffset = (
unsigned short)(timestamp-buffer->m_firstTimestamp);
527 buffer->m_lastItemPositionW = positionW;
528 buffer->m_firstFreePositionW = positionW+sizeW;
529 buffer->m_lastTimestamp = timestamp;
530 block = positionW>>channel->m_positionToBlockShiftW;
531 buffer->lookup[block].m_offsetW = positionW&channel->m_positionToOffsetMaskW;
532 buffer->lookup[block].m_timeOffset = item->
m_timeOffset;
534 buffer->m_firstFreePositionW = buffer->m_lastItemPositionW+item->
m_sizeW;
535 channel->m_lastBuffer = buffer;
536 channel->m_lastItemPositionW = positionW;
537 channel->m_lastTimestamp = timestamp;
542 memcpy(itemData, data, length);
604 const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp);
606 if (!item || item->
m_sizeW != sizeW)
607 return (
double*)
addCacheItem(device, channel, timestamp, newdata, length*
sizeof(
double));
611 double *ref = olddata;
614 for (i=length; i>0; --i) {
615 if (
fabs(*
v-*ref) > threshold)
620 olddata = (
double*)
addCacheItem(device, channel, timestamp, newdata, length*
sizeof(
double));
CacheChannel * m_channelArray