Copy a range of bytes from entire bitmap and store them into ArrayBitfieldBitmap.
| 732 | |
| 733 | // Copy a range of bytes from entire bitmap and store them into ArrayBitfieldBitmap. |
| 734 | static rocksdb::Status CopySegmentsBytesToBitfield(engine::Context &ctx, Bitmap::SegmentCacheStore &store, |
| 735 | uint32_t byte_offset, uint32_t bytes, |
| 736 | ArrayBitfieldBitmap *bitfield) { |
| 737 | bitfield->SetByteOffset(byte_offset); |
| 738 | bitfield->Reset(); |
| 739 | |
| 740 | uint32_t segment_index = byte_offset / kBitmapSegmentBytes; |
| 741 | int64_t remain_bytes = bytes; |
| 742 | // the byte_offset in current segment. |
| 743 | auto segment_byte_offset = static_cast<int>(byte_offset % kBitmapSegmentBytes); |
| 744 | for (; remain_bytes > 0; ++segment_index) { |
| 745 | const std::string *cache = nullptr; |
| 746 | auto cache_status = store.Get(ctx, segment_index, &cache); |
| 747 | if (!cache_status.ok()) { |
| 748 | return cache_status; |
| 749 | } |
| 750 | |
| 751 | auto cache_size = static_cast<int>(cache->size()); |
| 752 | auto copyable = std::max(0, cache_size - segment_byte_offset); |
| 753 | auto copy_count = std::min(static_cast<int>(remain_bytes), copyable); |
| 754 | auto src = reinterpret_cast<const uint8_t *>(cache->data() + segment_byte_offset); |
| 755 | auto status = bitfield->Set(byte_offset, copy_count, src); |
| 756 | if (!status) { |
| 757 | return rocksdb::Status::InvalidArgument(); |
| 758 | } |
| 759 | |
| 760 | // next segment will copy from its front. |
| 761 | byte_offset = (segment_index + 1) * kBitmapSegmentBytes; |
| 762 | // maybe negative, but still correct. |
| 763 | remain_bytes -= kBitmapSegmentBytes - segment_byte_offset; |
| 764 | segment_byte_offset = 0; |
| 765 | } |
| 766 | |
| 767 | return rocksdb::Status::OK(); |
| 768 | } |
| 769 | |
| 770 | static rocksdb::Status GetBitfieldInteger(const ArrayBitfieldBitmap &bitfield, uint32_t bit_offset, |
| 771 | BitfieldEncoding enc, uint64_t *res) { |
no test coverage detected