| 553 | }; |
| 554 | |
| 555 | GetKeyValuesReply readRange(StorageCacheData* data, Version version, KeyRangeRef range, int limit, int* pLimitBytes) { |
| 556 | GetKeyValuesReply result; |
| 557 | StorageCacheData::VersionedData::ViewAtVersion view = data->data().at(version); |
| 558 | StorageCacheData::VersionedData::iterator vCurrent = view.end(); |
| 559 | KeyRef readBegin; |
| 560 | KeyRef readEnd; |
| 561 | KeyRef rangeBegin = range.begin; |
| 562 | KeyRef rangeEnd = range.end; |
| 563 | int accumulatedBytes = 0; |
| 564 | // printf("\nSCReadRange\n"); |
| 565 | |
| 566 | // if (limit >= 0) we are reading forward, else backward |
| 567 | if (limit >= 0) { |
| 568 | // We might care about a clear beginning before start that runs into range |
| 569 | vCurrent = view.lastLessOrEqual(rangeBegin); |
| 570 | if (vCurrent && vCurrent->isClearTo() && vCurrent->getEndKey() > rangeBegin) |
| 571 | readBegin = vCurrent->getEndKey(); |
| 572 | else |
| 573 | readBegin = rangeBegin; |
| 574 | |
| 575 | vCurrent = view.lower_bound(readBegin); |
| 576 | ASSERT(!vCurrent || vCurrent.key() >= readBegin); |
| 577 | if (vCurrent) { |
| 578 | auto b = vCurrent; |
| 579 | --b; |
| 580 | ASSERT(!b || b.key() < readBegin); |
| 581 | } |
| 582 | accumulatedBytes = 0; |
| 583 | while (vCurrent && vCurrent.key() < rangeEnd && limit > 0 && accumulatedBytes < *pLimitBytes) { |
| 584 | if (!vCurrent->isClearTo()) { |
| 585 | result.data.push_back_deep(result.arena, KeyValueRef(vCurrent.key(), vCurrent->getValue())); |
| 586 | accumulatedBytes += sizeof(KeyValueRef) + result.data.end()[-1].expectedSize(); |
| 587 | --limit; |
| 588 | } |
| 589 | ++vCurrent; |
| 590 | } |
| 591 | } else { // reverse readRange |
| 592 | vCurrent = view.lastLess(rangeEnd); |
| 593 | |
| 594 | // A clear might extend all the way to range.end |
| 595 | if (vCurrent && vCurrent->isClearTo() && vCurrent->getEndKey() >= rangeEnd) { |
| 596 | readEnd = vCurrent.key(); |
| 597 | --vCurrent; |
| 598 | } else { |
| 599 | readEnd = rangeEnd; |
| 600 | } |
| 601 | ASSERT(!vCurrent || vCurrent.key() < readEnd); |
| 602 | if (vCurrent) { |
| 603 | auto b = vCurrent; |
| 604 | --b; |
| 605 | ASSERT(!b || b.key() >= readEnd); |
| 606 | } |
| 607 | accumulatedBytes = 0; |
| 608 | while (vCurrent && vCurrent.key() >= rangeEnd && limit > 0 && accumulatedBytes < *pLimitBytes) { |
| 609 | if (!vCurrent->isClearTo()) { |
| 610 | result.data.push_back_deep(result.arena, KeyValueRef(vCurrent.key(), vCurrent->getValue())); |
| 611 | accumulatedBytes += sizeof(KeyValueRef) + result.data.end()[-1].expectedSize(); |
| 612 | --limit; |
no test coverage detected