blob: d8cdd978a9bf51ec8399897c3a806076266be79c [file] [log] [blame]
// Copyright 2020 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_VOLUME_IMAGE_UTILS_EXTENT_H_
#define SRC_STORAGE_VOLUME_IMAGE_UTILS_EXTENT_H_
#include <lib/fit/result.h>
#include <cstdint>
#include <tuple>
namespace storage::volume_image {
// An extent represents a collection of contiguous 'blocks' from a given offset in some device or
// block container. The size of the block is determined by the storage media.
class Extent {
public:
// The tail is the padding adding to fill the remainder of the last block, when converting between
// extents of different block sizes.
struct Tail {
constexpr Tail() = default;
constexpr Tail(uint64_t offset, uint64_t count) : offset(offset), count(count) {}
// Returns true if the tail is empty.
constexpr bool empty() const { return count == 0; }
// Offset in bytes where the tail starts in the last block of the extent.
uint64_t offset = 0;
// Number of bytes in the tail.
// This should be equal to the remainder of the block(block size - offset).
uint64_t count = 0;
};
constexpr Extent() = default;
constexpr Extent(uint64_t offset, uint64_t count, uint64_t block_size)
: offset_(offset), count_(count), block_size_(block_size) {}
constexpr Extent(const Extent&) = default;
constexpr Extent(Extent&&) = default;
constexpr Extent& operator=(const Extent&) = default;
constexpr Extent& operator=(Extent&&) = default;
~Extent() = default;
// Returns a conversion of this extent to represent an extent in another storage medium at
// |offset| with |block_size|.
// |Tail| represents extra space added so the data in this extent is block aligned in the
// converted extent.
std::tuple<Extent, Tail> Convert(uint64_t offset, uint64_t block_size) const;
// Returns the offset where this extent starts.
constexpr uint64_t offset() const { return offset_; }
// Returns the number of blocks contained in this extent.
constexpr uint64_t count() const { return count_; }
// Returns the block size by storage this extents represents.
constexpr uint64_t block_size() const { return block_size_; }
// Returns true if there are no blocks in this extent.
constexpr bool empty() const { return begin() == end(); }
// Returns the offset of the first block in the extent.
constexpr uint64_t begin() const { return offset_; }
// Returns non-inclusive offset past the last block.
constexpr uint64_t end() const { return offset_ + count_; }
private:
// Offset in blocks where the extent starts.
uint64_t offset_ = 0;
// Number of blocks in this extent.
uint64_t count_ = 0;
// Block size in bytes used for this extent.
uint64_t block_size_ = 0;
};
} // namespace storage::volume_image
#endif // SRC_STORAGE_VOLUME_IMAGE_UTILS_EXTENT_H_