| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_STORAGE_FVM_DRIVER_SLICE_EXTENT_H_ |
| #define SRC_STORAGE_FVM_DRIVER_SLICE_EXTENT_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| |
| #include <fbl/alloc_checker.h> |
| #include <fbl/intrusive_wavl_tree.h> |
| #include <fbl/vector.h> |
| |
| #include "src/storage/fvm/format.h" |
| |
| namespace fvm { |
| |
| class SliceExtent : public fbl::WAVLTreeContainable<std::unique_ptr<SliceExtent>> { |
| public: |
| SliceExtent() = delete; |
| explicit SliceExtent(uint64_t vslice_start) : vslice_start_(vslice_start) {} |
| SliceExtent(const SliceExtent&) = delete; |
| SliceExtent(SliceExtent&&) = delete; |
| SliceExtent& operator=(const SliceExtent&) = delete; |
| SliceExtent& operator=(SliceExtent&&) = delete; |
| ~SliceExtent() = default; |
| |
| uint64_t GetKey() const { return vslice_start_; } |
| |
| // Virtual slice offset of the start of the extent (inclusive) |
| uint64_t start() const { return vslice_start_; } |
| |
| // Virtual slice offset of the end of the extent (exclusive) |
| uint64_t end() const { return vslice_start_ + pslices_.size(); } |
| |
| // Extent length, in slices |
| uint64_t size() const { return end() - start(); } |
| |
| // Look up a pslice given a vslice |
| bool find(uint64_t vslice, uint64_t* out_pslice) const { |
| size_t offset = vslice - vslice_start_; |
| if (offset >= pslices_.size()) { |
| return false; |
| } |
| *out_pslice = at(vslice); |
| return true; |
| } |
| |
| uint64_t at(uint64_t vslice) const { |
| ZX_ASSERT(vslice >= vslice_start_); |
| uint64_t offset = vslice - vslice_start_; |
| ZX_ASSERT(offset < pslices_.size()); |
| return pslices_[offset]; |
| } |
| |
| bool contains(uint64_t vslice) const { |
| uint64_t pslice; |
| return find(vslice, &pslice); |
| } |
| |
| // Breaks the extent from: |
| // [start(), end()) |
| // Into: |
| // [start(), vslice] and [vslice + 1, end()). |
| // Returns the latter extent on success; returns nullptr |
| // if a memory allocation failure occurs. |
| std::unique_ptr<SliceExtent> Split(uint64_t vslice); |
| |
| // Combines the other extent into this one. |
| // 'other' must immediately follow the current slice. |
| void Merge(const SliceExtent& other); |
| |
| void push_back(uint64_t pslice) { pslices_.push_back(pslice); } |
| |
| void pop_back() { pslices_.pop_back(); } |
| |
| bool empty() const { return pslices_.size() == 0; } |
| |
| private: |
| friend class TypeWAVLTraits; |
| |
| fbl::Vector<uint64_t> pslices_; |
| const uint64_t vslice_start_; |
| }; |
| |
| } // namespace fvm |
| |
| #endif // SRC_STORAGE_FVM_DRIVER_SLICE_EXTENT_H_ |