blob: 0ece85f9b1f3c56a8b1b3186d2ef83a3ba640761 [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 "src/ledger/bin/storage/impl/live_commit_tracker.h"
#include <lib/fit/function.h>
#include <lib/zx/time.h>
#include <algorithm>
#include <iterator>
#include <memory>
#include <tuple>
#include "src/ledger/bin/storage/public/commit.h"
#include "src/ledger/bin/storage/public/types.h"
namespace storage {
bool LiveCommitTracker::CommitComparator::operator()(
const std::unique_ptr<const Commit>& left, const std::unique_ptr<const Commit>& right) const {
return operator()(left.get(), right.get());
}
bool LiveCommitTracker::CommitComparator::operator()(const Commit* left,
const Commit* right) const {
return std::forward_as_tuple(left->GetTimestamp(), left->GetId()) <
std::forward_as_tuple(right->GetTimestamp(), right->GetId());
}
LiveCommitTracker::~LiveCommitTracker() {
// The only live commits in this object at destruction time must be head
// commits.
FXL_DCHECK(std::all_of(live_commits_.begin(), live_commits_.end(), [this](const Commit* commit) {
return std::find_if(heads_.begin(), heads_.end(),
[commit](const std::unique_ptr<const Commit>& element) {
return element.get() == commit;
}) != heads_.end();
}));
}
void LiveCommitTracker::AddHeads(std::vector<std::unique_ptr<const Commit>> heads) {
heads_.insert(std::make_move_iterator(heads.begin()), std::make_move_iterator(heads.end()));
}
void LiveCommitTracker::RemoveHeads(const std::vector<CommitId>& commit_ids) {
for (const auto& commit_id : commit_ids) {
auto it = std::find_if(
heads_.begin(), heads_.end(),
[&commit_id](const std::unique_ptr<const Commit>& p) { return p->GetId() == commit_id; });
if (it != heads_.end()) {
heads_.erase(it);
}
}
}
std::vector<std::unique_ptr<const Commit>> LiveCommitTracker::GetHeads() const {
auto result = std::vector<std::unique_ptr<const Commit>>();
result.reserve(heads_.size());
std::transform(heads_.begin(), heads_.end(), std::back_inserter(result),
[](const auto& p) -> std::unique_ptr<const Commit> { return p->Clone(); });
return result;
}
void LiveCommitTracker::RegisterCommit(Commit* commit) {
auto result = live_commits_.insert(commit);
// Verifies that this is indeed a new commit, and not an already known commit.
FXL_DCHECK(result.second);
}
void LiveCommitTracker::UnregisterCommit(Commit* commit) {
auto erased = live_commits_.erase(commit);
// Verifies that the commit was registered previously.
FXL_DCHECK(erased != 0);
}
std::vector<std::unique_ptr<const Commit>> LiveCommitTracker::GetLiveCommits() {
// This deduplicates identical commits.
std::set<const Commit*, CommitComparator> live(live_commits_.begin(), live_commits_.end());
std::vector<std::unique_ptr<const Commit>> commits;
for (const Commit* commit : live) {
commits.emplace_back(commit->Clone());
}
return commits;
}
} // namespace storage