diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2021-03-04 10:58:11 +0100 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2021-03-04 11:06:03 +0100 |
commit | 4a33bf931364094528f30775e1b3f5e1df372fc8 (patch) | |
tree | d41ea8d328653bb5e373963a53666d3df2e62bbb /vespalib | |
parent | a815447f4de43fd276aa20609d1727d0fe365220 (diff) |
Factor out prepare_reuse_area to separate member function.
Add comments for _free_areas and _free_sizes.
Diffstat (limited to 'vespalib')
-rw-r--r-- | vespalib/src/vespa/vespalib/util/file_area_freelist.cpp | 30 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/util/file_area_freelist.h | 5 |
2 files changed, 25 insertions, 10 deletions
diff --git a/vespalib/src/vespa/vespalib/util/file_area_freelist.cpp b/vespalib/src/vespa/vespalib/util/file_area_freelist.cpp index ac6c2263112..5edebcac1ad 100644 --- a/vespalib/src/vespa/vespalib/util/file_area_freelist.cpp +++ b/vespalib/src/vespa/vespalib/util/file_area_freelist.cpp @@ -26,27 +26,41 @@ FileAreaFreeList::remove_from_size_set(uint64_t offset, size_t size) } } -uint64_t -FileAreaFreeList::alloc(size_t size) +std::pair<uint64_t, size_t> +FileAreaFreeList::prepare_reuse_area(size_t size) { - auto sitr = _free_sizes.lower_bound(size); - if (sitr == _free_sizes.end()) { - return bad_offset; // No free areas of sufficient size + auto itr = _free_sizes.lower_bound(size); + if (itr == _free_sizes.end()) { + return std::make_pair(bad_offset, 0); // No free areas of sufficient size } - auto old_size = sitr->first; + auto old_size = itr->first; assert(old_size >= size); - auto &offsets = sitr->second; + auto &offsets = itr->second; assert(!offsets.empty()); auto oitr = offsets.begin(); auto offset = *oitr; offsets.erase(oitr); if (offsets.empty()) { - _free_sizes.erase(sitr); + _free_sizes.erase(itr); + } + // Note: Caller must update _free_areas + return std::make_pair(offset, old_size); +} + +uint64_t +FileAreaFreeList::alloc(size_t size) +{ + auto reuse_candidate = prepare_reuse_area(size); + auto offset = reuse_candidate.first; + if (offset == bad_offset) { + return bad_offset; // No free areas of sufficient size } auto fa_itr = _free_areas.find(offset); assert(fa_itr != _free_areas.end()); fa_itr = _free_areas.erase(fa_itr); + auto old_size = reuse_candidate.second; if (old_size > size) { + // Old area beyond what we reuse should still be a free area. auto ins_res = _free_sizes[old_size - size].insert(offset + size); assert(ins_res.second); _free_areas.emplace_hint(fa_itr, offset + size, old_size - size); diff --git a/vespalib/src/vespa/vespalib/util/file_area_freelist.h b/vespalib/src/vespa/vespalib/util/file_area_freelist.h index 8b245084585..ad56f516d26 100644 --- a/vespalib/src/vespa/vespalib/util/file_area_freelist.h +++ b/vespalib/src/vespa/vespalib/util/file_area_freelist.h @@ -13,9 +13,10 @@ namespace vespalib::alloc { * Class that tracks free areas in a file. */ class FileAreaFreeList { - std::map<uint64_t, size_t> _free_areas; - std::map<size_t, std::set<uint64_t>> _free_sizes; + std::map<uint64_t, size_t> _free_areas; // map from offset to size + std::map<size_t, std::set<uint64_t>> _free_sizes; // map from size to set of offsets void remove_from_size_set(uint64_t offset, size_t size); + std::pair<uint64_t, size_t> prepare_reuse_area(size_t size); public: FileAreaFreeList(); ~FileAreaFreeList(); |