blob: b0e1b143a12ab37d664c34d8ca8ecbb6b56fba11 [file] [log] [blame]
// 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_