STL Memory Versioning
versioned.h
Go to the documentation of this file.
1 
7 #ifndef __VERSIONED_H__
8 #define __VERSIONED_H__
9 
10 #include <iostream>
11 #include <memory>
12 #include <map>
13 #include "revision.h"
14 #include "segment.h"
15 
21 {
22 public:
23  virtual void Release(std::shared_ptr<Segment> release) = 0;
24  virtual void Collapse(std::shared_ptr<Revision> main, std::shared_ptr<Segment> parent) = 0;
25  virtual void Merge(std::shared_ptr<Revision> main, std::shared_ptr<Revision> joinRev, std::shared_ptr<Segment> join) = 0;
26 };
27 
28 /* XXX: not really fits isMergeStrategy concept (no key and container here), but anyway */
29 template<typename T>
31 {
32  public:
33 
34  void
35  merge(T& dst, T& src)
36  {
37  dst = src;
38  }
39 
40  // void
41  // merge_same_element(T& dst, _Key& dstk, _Key& srck)
42  // {
43  // /* pretend we didnt saw new elements */
44  // }
45 };
46 
52 template <class T, typename _Strategy = DefaultMergeStrategy<T>>
53 class Versioned : public VersionedI {
54 public:
61  std::map<int, T> versions;
62 
68  Versioned(const T& val);
69 
76 
83  const T& Get() const;
84 
96  bool Set(const T& v, const std::function<bool(T&)>& updater = nullptr);
97 
104  void Release(std::shared_ptr<Segment> release) override;
105 
112  void Collapse(std::shared_ptr<Revision> main, std::shared_ptr<Segment> parent) override;
113 
121  void Merge(std::shared_ptr<Revision> main, std::shared_ptr<Revision> joinRev, std::shared_ptr<Segment> join) override;
122 
123 private:
124 
131  const T& Get(std::shared_ptr<Revision> r) const;
132 
145  bool Set(std::shared_ptr<Revision> r, const T& value, const std::function<bool(T&)>& updater = nullptr);
146 
147 
151  bool SetMerge(std::shared_ptr<Revision> r, T& value);
152 
156  _Strategy merge_strategy;
157 };
158 
159 
160 // All methods need to be decalred in header due to template linking issues
161 
162 template <class T, typename _Strategy>
165 }
166 
167 template <class T, typename _Strategy>
169 {
170  std::shared_ptr<Segment> s = Revision::currentRevision->current;
171 
172  while (s) {
173  if (versions.find(s->version) != versions.end()) {
174  for (auto it = s->written.begin(); it != s->written.end();){
175  if (*it == this)
176  it = s->written.erase(it);
177  else
178  it++;
179  }
180  }
181  s = s->parent;
182  }
183 }
184 
185 template <class T, typename _Strategy>
187  return Get(Revision::currentRevision);
188 }
189 
190 template <class T, typename _Strategy>
191 const T& Versioned<T,_Strategy>::Get(std::shared_ptr<Revision> r) const{
192  std::shared_ptr<Segment> s = r->current;
193 
194  while (versions.find(s->version) == versions.end()) {
195  if (!s->parent)
196  break;
197 
198  s = s->parent;
199  }
200 
201  return versions.at(s->version);
202 }
203 
204 template <class T, typename _Strategy>
205 bool Versioned<T,_Strategy>::Set(const T& v, const std::function<bool(T&)>& updater) {
206  return Set(Revision::currentRevision, v, updater);
207 }
208 
209 template <class T, typename _Strategy>
210 bool Versioned<T,_Strategy>::Set(std::shared_ptr<Revision> r, const T& value, const std::function<bool(T&)>& updater) {
211  if (versions.find(r->current->version) == versions.end()) {
212  r->current->written.push_back(this);
213  versions[r->current->version] = value;
214  if (updater){
215  return updater(versions[r->current->version]);
216  }
217  } else {
218  if (updater){
219  return updater(versions[r->current->version]);
220  } else {
221  versions[r->current->version] = value;
222  }
223  }
224  return true;
225 }
226 
227 template <class T, typename _Strategy>
228 bool Versioned<T,_Strategy>::SetMerge(std::shared_ptr<Revision> r, T& value){
229  if (versions.find(r->current->version) == versions.end()) {
230  r->current->written.push_back(this);
231  versions[r->current->version] = value;
232  } else {
233  merge_strategy.merge(versions[r->current->version], value);
234  }
235  return true;
236 }
237 
238 template <class T, typename _Strategy>
239 void Versioned<T,_Strategy>::Release(std::shared_ptr<Segment> release) {
240  versions.erase(release->version);
241 }
242 
243 template <class T, typename _Strategy>
244 void Versioned<T,_Strategy>::Collapse(std::shared_ptr<Revision> main, std::shared_ptr<Segment> parent) {
245  if (versions.find(main->current->version) == versions.end()) {
246  Set(main, versions[parent->version]);
247  }
248  Release(parent);
249 }
250 
251 template <class T, typename _Strategy>
252 void Versioned<T,_Strategy>::Merge(std::shared_ptr<Revision> main, std::shared_ptr<Revision> joinRev, std::shared_ptr<Segment> join) {
253  std::shared_ptr<Segment> s = joinRev->current;
254  while (versions.find(s->version) == versions.end()) {
255  if (!s->parent)
256  break;
257 
258  s = s->parent;
259  }
260  if (s == join) {
261  SetMerge(main, versions[join->version]);
262  }
263 }
264 
265 #endif
void merge(T &dst, T &src)
Definition: versioned.h:35
static thread_local std::shared_ptr< Revision > currentRevision
The current Revision for current thread.
Definition: revision.h:65
Interface for all Versioned classes.
Definition: versioned.h:21
virtual void Merge(std::shared_ptr< Revision > main, std::shared_ptr< Revision > joinRev, std::shared_ptr< Segment > join)=0
virtual void Release(std::shared_ptr< Segment > release)=0
virtual void Collapse(std::shared_ptr< Revision > main, std::shared_ptr< Segment > parent)=0
Wrapper to make any class Versioned.
Definition: versioned.h:53
void Collapse(std::shared_ptr< Revision > main, std::shared_ptr< Segment > parent) override
Collapse all changes made in Revision into one.
Definition: versioned.h:244
void Release(std::shared_ptr< Segment > release) override
Forget version that was changed in some Segment.
Definition: versioned.h:239
Versioned(const T &val)
Construct a new Versioned object from your object.
Definition: versioned.h:163
~Versioned()
Destroy the Versioned object.
Definition: versioned.h:168
std::map< int, T > versions
Map of all versions of specified object.
Definition: versioned.h:61
const T & Get() const
Get the current value of the object in the current Revision.
Definition: versioned.h:186
void Merge(std::shared_ptr< Revision > main, std::shared_ptr< Revision > joinRev, std::shared_ptr< Segment > join) override
Merge changes from two Revisions.
Definition: versioned.h:252
bool Set(const T &v, const std::function< bool(T &)> &updater=nullptr)
Set new value of the object.
Definition: versioned.h:205
Implementation of the class Revision.
Implementation of the class Segment.