diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.cpp | 47 | ||||
| -rw-r--r-- | src/storage.cpp | 69 | ||||
| -rw-r--r-- | src/storage.h | 3 | 
3 files changed, 119 insertions, 0 deletions
| diff --git a/src/main.cpp b/src/main.cpp index cb9002e..a3facea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,8 @@  #include <erebos/storage.h>  #include <erebos/sync.h> +#include "storage.h" +  #include <arpa/inet.h>  #include <netinet/in.h>  #include <sys/socket.h> @@ -37,6 +39,7 @@ using std::promise;  using std::scoped_lock;  using std::string;  using std::thread; +using std::to_string;  using std::unique_ptr;  using std::vector; @@ -104,6 +107,48 @@ struct Command  	function<void(const vector<string> &)> action;  }; +void store(const vector<string> & args) +{ +	auto type = args.at(0); + +	vector<uint8_t> inner, data; + +	char * line = nullptr; +	size_t size = 0; + +	while (getline(&line, &size, stdin) > 0 && strlen(line) > 1) +		copy(line, line + strlen(line), std::back_inserter(inner)); + +	free(line); + +	auto inserter = std::back_inserter(data); +	copy(type.begin(), type.end(), inserter); +	inserter = ' '; + +	auto slen = to_string(inner.size()); +	copy(slen.begin(), slen.end(), inserter); +	inserter = '\n'; + +	copy(inner.begin(), inner.end(), inserter); + +	auto digest = st.priv().storeBytes(data); + +	ostringstream ss; +	ss << "store-done " << string(digest); +	printLine(ss.str()); +} + +void storedGeneration(const vector<string> & args) +{ +	auto ref = st.ref(Digest(args.at(0))); +	if (!ref) +		throw invalid_argument("ref " + args.at(0) + " not found"); + +	ostringstream ss; +	ss << "stored-generation " << string(ref->digest()) << " " << string(ref->generation()); +	printLine(ss.str()); +} +  void createIdentity(const vector<string> & args)  {  	optional<Identity> identity; @@ -292,6 +337,8 @@ void attachReject(const vector<string> & params)  }  vector<Command> commands = { +	{ "store", store }, +	{ "stored-generation", storedGeneration },  	{ "create-identity", createIdentity },  	{ "start-server", startServer },  	{ "stop-server", stopServer }, diff --git a/src/storage.cpp b/src/storage.cpp index 05b100a..5784309 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -979,6 +979,56 @@ const Storage & Ref::storage() const  	return *static_cast<const Storage*>(p->storage.get());  } +vector<Ref> Ref::previous() const +{ +	auto rec = (**this).asRecord(); +	if (!rec) +		return {}; + +	vector<Ref> res; + +	auto sdata = rec->item("SDATA").asRef(); +	if (sdata) { +		auto drec = sdata.value()->asRecord(); +		if (!drec) +			return {}; + +		for (const Record::Item & i : drec->items("SPREV")) +			if (auto x = i.asRef()) +				res.push_back(*x); +		return res; +	} + +	for (const Record::Item & i : rec->items("PREV")) +		if (auto x = i.asRef()) +			res.push_back(*x); +	return res; +} + +Generation Ref::generation() const +{ +	scoped_lock lock(p->storage->p->generationCacheLock); +	return generationLocked(); +} + +Generation Ref::generationLocked() const +{ +	auto it = p->storage->p->generationCache.find(p->digest); +	if (it != p->storage->p->generationCache.end()) +		return it->second; + +	auto prev = previous(); +	vector<Generation> pgen; +	pgen.reserve(prev.size()); +	for (const auto & r : prev) +		pgen.push_back(r.generationLocked()); + +	auto gen = Generation::next(pgen); + +	p->storage->p->generationCache.emplace(p->digest, gen); +	return gen; +} +  template<class S>  RecordT<S>::Item::operator bool() const @@ -1366,6 +1416,25 @@ optional<Blob> ObjectT<S>::asBlob() const  template class erebos::ObjectT<Storage>;  template class erebos::ObjectT<PartialStorage>; + +Generation::Generation(): Generation(0) {} +Generation::Generation(size_t g): gen(g) {} + +Generation Generation::next(const vector<Generation> & prev) +{ +	Generation ret; +	for (const auto g : prev) +		if (ret.gen <= g.gen) +			ret.gen = g.gen + 1; +	return ret; +} + +Generation::operator string() const +{ +	return to_string(gen); +} + +  vector<Stored<Object>> erebos::collectStoredObjects(const Stored<Object> & from)  {  	unordered_set<Digest> seen; diff --git a/src/storage.h b/src/storage.h index 0f7c3bf..ef335b8 100644 --- a/src/storage.h +++ b/src/storage.h @@ -164,6 +164,9 @@ struct PartialStorage::Priv  	optional<Digest> copy(const typename S::Ref &, vector<Digest> *) const;  	template<class S>  	optional<Digest> copy(const ObjectT<S> &, vector<Digest> *) const; + +	mutable mutex generationCacheLock {}; +	mutable unordered_map<Digest, Generation> generationCache {};  };  struct PartialRef::Priv |