[ledger] Allow creating a TreeNode from an Object
Also discard unused method TreeNode::GetChild, which removes the need to
keep a PageStorage reference in TreeNode.
Change-Id: Ibdc9ea1d4f7b04c0edd5b535ba9554c1f6ae8b62
Bug: LE-697
Tested: fx run-test ledger_tests -t ledger_unittests
diff --git a/src/ledger/bin/storage/impl/btree/tree_node.cc b/src/ledger/bin/storage/impl/btree/tree_node.cc
index 2201526..e6a4f9b 100644
--- a/src/ledger/bin/storage/impl/btree/tree_node.cc
+++ b/src/ledger/bin/storage/impl/btree/tree_node.cc
@@ -24,11 +24,10 @@
namespace storage {
namespace btree {
-TreeNode::TreeNode(PageStorage* page_storage, ObjectIdentifier identifier,
- uint8_t level, std::vector<Entry> entries,
+TreeNode::TreeNode(ObjectIdentifier identifier, uint8_t level,
+ std::vector<Entry> entries,
std::map<size_t, ObjectIdentifier> children)
- : page_storage_(page_storage),
- identifier_(std::move(identifier)),
+ : identifier_(std::move(identifier)),
level_(level),
entries_(std::move(entries)),
children_(std::move(children)) {
@@ -42,19 +41,36 @@
fit::function<void(Status, std::unique_ptr<const TreeNode>)> callback) {
page_storage->GetObject(
identifier, PageStorage::Location::NETWORK,
- [page_storage, identifier, callback = std::move(callback)](
+ [identifier, callback = std::move(callback)](
Status status, std::unique_ptr<const Object> object) mutable {
if (status != Status::OK) {
callback(status, nullptr);
return;
}
std::unique_ptr<const TreeNode> node;
- status = FromObject(page_storage, std::move(identifier),
- std::move(object), &node);
+ status = FromObject(*object, &node);
callback(status, std::move(node));
});
}
+Status TreeNode::FromObject(const Object& object,
+ std::unique_ptr<const TreeNode>* node) {
+ fxl::StringView data;
+ Status status = object.GetData(&data);
+ if (status != Status::OK) {
+ return status;
+ }
+ uint8_t level;
+ std::vector<Entry> entries;
+ std::map<size_t, ObjectIdentifier> children;
+ if (!DecodeNode(data, &level, &entries, &children)) {
+ return Status::FORMAT_ERROR;
+ }
+ node->reset(new TreeNode(object.GetIdentifier(), level, std::move(entries),
+ std::move(children)));
+ return Status::OK;
+}
+
void TreeNode::Empty(PageStorage* page_storage,
fit::function<void(Status, ObjectIdentifier)> callback) {
FromEntries(page_storage, 0u, std::vector<Entry>(),
@@ -95,19 +111,6 @@
return Status::OK;
}
-void TreeNode::GetChild(
- int index,
- fit::function<void(Status, std::unique_ptr<const TreeNode>)> callback)
- const {
- FXL_DCHECK(index >= 0 && index <= GetKeyCount());
- const auto it = children_.find(index);
- if (it == children_.end()) {
- callback(Status::NO_SUCH_CHILD, nullptr);
- return;
- }
- return FromIdentifier(page_storage_, it->second, std::move(callback));
-}
-
Status TreeNode::FindKeyOrChild(convert::ExtendedStringView key,
int* index) const {
if (key.empty()) {
@@ -133,25 +136,5 @@
const ObjectIdentifier& TreeNode::GetIdentifier() const { return identifier_; }
-Status TreeNode::FromObject(PageStorage* page_storage,
- ObjectIdentifier identifier,
- std::unique_ptr<const Object> object,
- std::unique_ptr<const TreeNode>* node) {
- fxl::StringView data;
- Status status = object->GetData(&data);
- if (status != Status::OK) {
- return status;
- }
- uint8_t level;
- std::vector<Entry> entries;
- std::map<size_t, ObjectIdentifier> children;
- if (!DecodeNode(data, &level, &entries, &children)) {
- return Status::FORMAT_ERROR;
- }
- node->reset(new TreeNode(page_storage, std::move(identifier), level,
- std::move(entries), std::move(children)));
- return Status::OK;
-}
-
} // namespace btree
} // namespace storage
diff --git a/src/ledger/bin/storage/impl/btree/tree_node.h b/src/ledger/bin/storage/impl/btree/tree_node.h
index 6365a3a..24a58bc 100644
--- a/src/ledger/bin/storage/impl/btree/tree_node.h
+++ b/src/ledger/bin/storage/impl/btree/tree_node.h
@@ -23,28 +23,33 @@
public:
~TreeNode();
- // Creates a |TreeNode| object for an existing node and calls the given
- // |callback| with the returned status and node.
+ // Creates a |TreeNode| object in |page_storage| for an existing node and
+ // calls the given |callback| with the returned status and node.
static void FromIdentifier(
PageStorage* page_storage, ObjectIdentifier identifier,
fit::function<void(Status, std::unique_ptr<const TreeNode>)> callback);
- // Creates a |TreeNode| object with the given entries and children. |children|
- // is a map from the index of the child to the identifier of the child. It
- // only contains non-empty children. It is expected that all child indexes are
- // between |0| and |size(entries)| (included). The |callback| will be called
- // with the success or error status and the id of the new node.
+ // Creates a |TreeNode| object in |page_storage| with the given entries and
+ // children. |children| is a map from the index of the child to the identifier
+ // of the child. It only contains non-empty children. It is expected that all
+ // child indexes are between |0| and |size(entries)| (included). The
+ // |callback| will be called with the success or error status and the id of
+ // the new node.
static void FromEntries(
PageStorage* page_storage, uint8_t level,
const std::vector<Entry>& entries,
const std::map<size_t, ObjectIdentifier>& children,
fit::function<void(Status, ObjectIdentifier)> callback);
- // Creates an empty node, i.e. a TreeNode with no entries and an empty child
- // at index 0 and calls the callback with the result.
+ // Creates an empty node in |page_storage|, i.e. a TreeNode with no entries
+ // and an empty child at index 0 and calls the callback with the result.
static void Empty(PageStorage* page_storage,
fit::function<void(Status, ObjectIdentifier)> callback);
+ // Initializes |node| with a |TreeNode| object for an existing |object|.
+ static Status FromObject(const Object& object,
+ std::unique_ptr<const TreeNode>* node);
+
// Returns the number of entries stored in this tree node.
int GetKeyCount() const;
@@ -52,14 +57,6 @@
// to be in [0, GetKeyCount() - 1].
Status GetEntry(int index, Entry* entry) const;
- // Finds the child node at position |index| and calls the |callback| with the
- // result. |index| has to be in [0, GetKeyCount()]. If the child at the given
- // index is empty |NO_SUCH_CHILD| is returned and the value of |child| is not
- // updated.
- void GetChild(int index,
- fit::function<void(Status, std::unique_ptr<const TreeNode>)>
- callback) const;
-
// Searches for the given |key| in this node. If it is found, |OK| is
// returned and index contains the index of the entry. If not,
// |INTERNAL_NOT_FOUND| is returned and index stores the index of the child
@@ -77,18 +74,10 @@
}
private:
- TreeNode(PageStorage* page_storage, ObjectIdentifier identifier,
- uint8_t level, std::vector<Entry> entries,
+ TreeNode(ObjectIdentifier identifier, uint8_t level,
+ std::vector<Entry> entries,
std::map<size_t, ObjectIdentifier> children);
- // Creates a |TreeNode| object for an existing |object| and stores it in the
- // given |node|.
- static Status FromObject(PageStorage* page_storage,
- ObjectIdentifier identifier,
- std::unique_ptr<const Object> object,
- std::unique_ptr<const TreeNode>* node);
-
- PageStorage* page_storage_;
ObjectIdentifier identifier_;
const uint8_t level_;
const std::vector<Entry> entries_;
diff --git a/src/ledger/bin/storage/impl/btree/tree_node_unittest.cc b/src/ledger/bin/storage/impl/btree/tree_node_unittest.cc
index 219d2dc..02be759 100644
--- a/src/ledger/bin/storage/impl/btree/tree_node_unittest.cc
+++ b/src/ledger/bin/storage/impl/btree/tree_node_unittest.cc
@@ -96,7 +96,7 @@
EXPECT_EQ(Status::INTERNAL_NOT_FOUND, status);
}
-TEST_F(TreeNodeTest, GetEntryChild) {
+TEST_F(TreeNodeTest, GetEntry) {
int size = 10;
std::vector<Entry> entries;
ASSERT_TRUE(CreateEntries(size, &entries));
@@ -106,19 +106,6 @@
for (int i = 0; i < size; ++i) {
EXPECT_EQ(entries[i], GetEntry(node.get(), i));
}
-
- bool called;
- for (int i = 0; i <= size; ++i) {
- Status status;
- std::unique_ptr<const TreeNode> child;
- node->GetChild(i, callback::Capture(callback::SetWhenCalled(&called),
- &status, &child));
- RunLoopFor(kSufficientDelay);
- ASSERT_TRUE(called);
- ASSERT_EQ(Status::NO_SUCH_CHILD, status);
- EXPECT_EQ(node->children_identifiers().find(i),
- node->children_identifiers().end());
- }
}
TEST_F(TreeNodeTest, FindKeyOrChild) {