From b97b503408911130d24d7f07f9247dca8314a316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 1 Jan 2020 21:27:11 +0100 Subject: Respond to data requests from network --- src/storage.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 9 deletions(-) (limited to 'src/storage.cpp') diff --git a/src/storage.cpp b/src/storage.cpp index e611da0..0d9b52e 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -29,6 +29,7 @@ using std::runtime_error; using std::shared_ptr; using std::string; using std::to_string; +using std::tuple; optional Storage::open(fs::path path) { @@ -492,29 +493,52 @@ Blob Blob::decode(Storage, return Blob(make_shared>(begin, end)); } - -optional Object::decode(Storage st, const vector & data) +optional::const_iterator>> +Object::decodePrefix(Storage st, + vector::const_iterator begin, + vector::const_iterator end) { - auto newline = std::find(data.begin(), data.end(), '\n'); - if (newline == data.end()) + auto newline = std::find(begin, end, '\n'); + if (newline == end) return nullopt; - auto space = std::find(data.begin(), newline, ' '); + auto space = std::find(begin, newline, ' '); if (space == newline) return nullopt; ssize_t size = std::stoi(string(space + 1, newline)); - if (data.end() - newline - 1 != size) + if (end - newline - 1 < size) return nullopt; + auto cend = newline + 1 + size; - string type(data.begin(), space); + string type(begin, space); + optional obj; if (type == "rec") - return Object(Record::decode(st, newline + 1, data.end())); + obj.emplace(Record::decode(st, newline + 1, cend)); else if (type == "blob") - return Object(Blob::decode(st, newline + 1, data.end())); + obj.emplace(Blob::decode(st, newline + 1, cend)); else throw runtime_error("unknown object type '" + type + "'"); + if (obj) + return std::make_tuple(*obj, cend); + return nullopt; +} + +optional Object::decode(Storage st, const vector & data) +{ + return decode(st, data.begin(), data.end()); +} + +optional Object::decode(Storage st, + vector::const_iterator begin, + vector::const_iterator end) +{ + if (auto res = decodePrefix(st, begin, end)) { + auto [obj, next] = *res; + if (next == end) + return obj; + } return nullopt; } @@ -563,3 +587,28 @@ optional Object::asBlob() const return std::get(content); return nullopt; } + +vector> erebos::collectStoredObjects(const Stored & from) +{ + unordered_set seen; + vector> queue { from }; + vector> res; + + while (!queue.empty()) { + auto cur = queue.back(); + queue.pop_back(); + + auto [it, added] = seen.insert(cur.ref.digest()); + if (!added) + continue; + + res.push_back(cur); + + if (auto rec = cur->asRecord()) + for (const auto & item : rec->items()) + if (auto ref = item.asRef()) + queue.push_back(*Stored::load(*ref)); + } + + return res; +} -- cgit v1.2.3