blob: 340ede3de09a44042a8edbed5d379eb2eb361615 [file] [log] [blame]
// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once
#include <cstddef>
#include <cstdint>
namespace pw::kvs::internal {
// Tracks the available and used space in each sector used by the KVS.
class SectorDescriptor {
public:
explicit constexpr SectorDescriptor(uint16_t sector_size_bytes)
: tail_free_bytes_(sector_size_bytes), valid_bytes_(0) {}
SectorDescriptor(const SectorDescriptor&) = default;
SectorDescriptor& operator=(const SectorDescriptor&) = default;
// The number of bytes available to be written in this sector.
size_t writable_bytes() const { return tail_free_bytes_; }
void set_writable_bytes(uint16_t writable_bytes) {
tail_free_bytes_ = writable_bytes;
}
// The number of bytes of valid data in this sector.
size_t valid_bytes() const { return valid_bytes_; }
// Adds valid bytes without updating the writable bytes.
void AddValidBytes(uint16_t bytes) { valid_bytes_ += bytes; }
// Removes valid bytes without updating the writable bytes.
void RemoveValidBytes(uint16_t bytes) {
if (bytes > valid_bytes()) {
// TODO: use a DCHECK instead -- this is a programming error
valid_bytes_ = 0;
} else {
valid_bytes_ -= bytes;
}
}
// Removes writable bytes without updating the valid bytes.
void RemoveWritableBytes(uint16_t bytes) {
if (bytes > writable_bytes()) {
// TODO: use a DCHECK instead -- this is a programming error
tail_free_bytes_ = 0;
} else {
tail_free_bytes_ -= bytes;
}
}
bool HasSpace(size_t required_space) const {
return tail_free_bytes_ >= required_space;
}
bool Empty(size_t sector_size_bytes) const {
return tail_free_bytes_ == sector_size_bytes;
}
// Returns the number of bytes that would be recovered if this sector is
// garbage collected.
size_t RecoverableBytes(size_t sector_size_bytes) const {
return sector_size_bytes - valid_bytes_ - tail_free_bytes_;
}
private:
uint16_t tail_free_bytes_; // writable bytes at the end of the sector
uint16_t valid_bytes_; // sum of sizes of valid entries
};
} // namespace pw::kvs::internal