blob: be7eb7be3aef4985d54b827fde9536a3c58d3bd8 [file] [log] [blame]
// Copyright 2019 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.
#include "replay_tree.h"
#include <fs/transaction/writeback.h>
#include <storage/operation/buffered-operation.h>
namespace fs {
namespace internal {
// static.
zx_status_t RangeTraits::Update(const RangeContainer* other, uint64_t start, uint64_t end,
RangeContainer* obj) {
if (other) {
// Index by "dev_offset", but only allow merging BufferedOperations if:
// - Their dev offsets, lengths are contiguous (enforced by range library),
// - The difference between vmo offsets of an operation equals the difference
// between dev offsets.
//
// This enables merging between contiguous operations like:
// - vmo_offset = 1
// - dev_offset = 10
// - length = 1
// And
// - vmo_offset = 2
// - dev_offset = 11
// - length = 1
//
// But disallows merging between operations such as:
// - vmo_offset = 1
// - dev_offset = 10
// - length = 1
// And
// - vmo_offset = 5 <-- Not contiguous with prior operation!
// - dev_offset = 11
// - length = 1
if ((other->operation.op.vmo_offset - obj->operation.op.vmo_offset) !=
(other->operation.op.dev_offset - obj->operation.op.dev_offset)) {
return ZX_ERR_INVALID_ARGS;
}
}
obj->Update(start, end);
return ZX_OK;
}
} // namespace internal
ReplayTree::ReplayTree() = default;
void ReplayTree::insert(storage::BufferedOperation operation) {
internal::BufferedOperationRange range((internal::RangeContainer(operation)));
// Erase all prior operations which touch the same dev_offset.
tree_.erase(range);
// Utilize the newest operations touching dev_offset.
tree_.insert(range);
}
} // namespace fs