Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: blimp/net/helium/lww_register.h

Issue 2400303002: Add LwwRegister CRDT (Closed)
Patch Set: Add LwwRegister and tests to build Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BLIMP_NET_HELIUM_LWW_REGISTER_H_
6 #define BLIMP_NET_HELIUM_LWW_REGISTER_H_
7
8 #include "base/memory/ptr_util.h"
9 #include "blimp/common/proto/helium.pb.h"
10 #include "blimp/net/blimp_net_export.h"
11 #include "blimp/net/helium/lww_register_serializer.h"
12 #include "blimp/net/helium/syncable.h"
13 #include "blimp/net/helium/vector_clock.h"
14 #include "blimp/net/helium/vector_clock_generator.h"
15
16 namespace blimp {
17
18 enum class RunningAs { RunningAsClient, RunningAsEngine };
scf 2016/10/10 19:45:46 This should probably go into its own file as its g
CJ 2016/10/10 20:25:55 Could simplify the enums as just "Client" or "Engi
Kevin M 2016/10/10 20:50:21 +1. "enum class" is nice for enforcing prefixes.
steimel 2016/10/11 16:39:17 Done.
19 enum class LwwBias { ClientWins, EngineWins };
scf 2016/10/10 19:45:47 move this inside LwwRegister
Kevin M 2016/10/10 20:50:21 Could this just be factored out as "Bias"?
steimel 2016/10/11 16:39:17 LwwRegister is a templated class that is templated
20
21 template <class RegisterType, LwwBias bias>
Kevin M 2016/10/10 20:50:21 Add comments
steimel 2016/10/11 16:39:17 Done.
steimel 2016/10/11 16:39:17 Done.
22 class BLIMP_NET_EXPORT LwwRegister
23 : Syncable<proto::LwwRegisterChangesetMessage> {
24 public:
25 explicit LwwRegister(VectorClockGenerator* clock_gen, RunningAs running_as);
CJ 2016/10/07 22:07:54 Is there a particular reason why this has be to be
steimel 2016/10/07 22:53:39 You actually can implicitly construct with multipl
Kevin M 2016/10/10 20:50:21 What are the cases in which a two-param constructo
steimel 2016/10/11 16:39:17 Done.
26 ~LwwRegister();
27
28 void set(const RegisterType& state);
scf 2016/10/10 19:45:47 rename to |Set| as its a "complex" operation
steimel 2016/10/11 16:39:17 Done.
29
30 const RegisterType& state() const;
scf 2016/10/10 19:45:46 rename to get()
steimel 2016/10/11 16:39:17 Done.
31
32 // Syncable implementation.
33 bool ModifiedSince(const VectorClock& from) const override;
34 std::unique_ptr<proto::LwwRegisterChangesetMessage> CreateChangesetToCurrent(
35 const VectorClock& from) override;
36 void ApplyChangeset(
37 const VectorClock& from,
38 const VectorClock& to,
39 std::unique_ptr<proto::LwwRegisterChangesetMessage> changeset) override;
40 void ReleaseCheckpointsBefore(const VectorClock& checkpoint) override;
41
42 private:
43 VectorClockGenerator* clock_gen_;
44 VectorClock last_modified_;
45 RunningAs running_as_;
46 RegisterType state_;
scf 2016/10/10 19:45:47 provably rename to value_
steimel 2016/10/11 16:39:17 Done.
47
48 bool LocalWinsConflict() const;
49
50 DISALLOW_COPY_AND_ASSIGN(LwwRegister);
51 };
52
53 template <class RegisterType, LwwBias bias>
54 LwwRegister<RegisterType, bias>::LwwRegister(VectorClockGenerator* clock_gen,
55 RunningAs running_as)
56 : clock_gen_(clock_gen),
57 last_modified_(clock_gen->current()),
58 running_as_(running_as) {}
59
60 template <class RegisterType, LwwBias bias>
61 LwwRegister<RegisterType, bias>::~LwwRegister() = default;
scf 2016/10/10 19:45:46 dumb question, does the compiler complains this is
steimel 2016/10/11 16:39:17 Done.
62
63 template <class RegisterType, LwwBias bias>
64 void LwwRegister<RegisterType, bias>::set(const RegisterType& state) {
65 state_ = state;
66 clock_gen_->Increment();
67 last_modified_ = clock_gen_->current();
68 }
69
70 template <class RegisterType, LwwBias bias>
71 const RegisterType& LwwRegister<RegisterType, bias>::state() const {
72 return state_;
73 }
74
75 template <class RegisterType, LwwBias bias>
76 bool LwwRegister<RegisterType, bias>::ModifiedSince(
77 const VectorClock& from) const {
78 return from.local_revision() < last_modified_.local_revision();
79 }
80
81 template <class RegisterType, LwwBias bias>
82 std::unique_ptr<proto::LwwRegisterChangesetMessage>
83 LwwRegister<RegisterType, bias>::CreateChangesetToCurrent(
84 const VectorClock& from) {
85 std::unique_ptr<proto::LwwRegisterChangesetMessage> changeset =
86 base::MakeUnique<proto::LwwRegisterChangesetMessage>();
87 LwwRegisterSerializer<RegisterType>::SerializeLwwRegister(state_,
88 changeset.get());
89 return changeset;
90 }
91
92 template <class RegisterType, LwwBias bias>
93 void LwwRegister<RegisterType, bias>::ApplyChangeset(
94 const VectorClock& from,
95 const VectorClock& to,
96 std::unique_ptr<proto::LwwRegisterChangesetMessage> changeset) {
97 switch (last_modified_.CompareTo(to)) {
scf 2016/10/10 19:45:47 I find this a bit difficult to read. ``` if (don
steimel 2016/10/11 16:39:17 Done.
98 case VectorClock::Comparison::GreaterThan:
99 // We're ahead of this changeset, so do nothing.
100 break;
101 case VectorClock::Comparison::LessThan:
102 // We're behind this changeset, so set to given value.
103 LwwRegisterSerializer<RegisterType>::DeserializeLwwRegister(
104 state_, changeset.get());
105 break;
106 case VectorClock::Comparison::EqualTo:
107 // We're at the same revision as this changeset, so do nothing.
108 break;
109 case VectorClock::Comparison::Conflict:
110 // Conflict, so set to given value if we lose conflicts.
111 if (!LocalWinsConflict()) {
112 LwwRegisterSerializer<RegisterType>::DeserializeLwwRegister(
113 state_, changeset.get());
114 }
115 break;
116 }
117
118 last_modified_ = last_modified_.MergeWith(to);
119 }
120
121 template <class RegisterType, LwwBias bias>
122 void LwwRegister<RegisterType, bias>::ReleaseCheckpointsBefore(
123 const VectorClock& checkpoint) {
124 // no-op
125 }
126
127 template <class RegisterType, LwwBias bias>
Kevin M 2016/10/10 20:50:21 Move this to wherever it is that we will be stashi
steimel 2016/10/11 16:39:17 This particular function needs to know about inter
128 bool LwwRegister<RegisterType, bias>::LocalWinsConflict() const {
129 switch (running_as_) {
130 case RunningAs::RunningAsClient:
131 return bias == LwwBias::ClientWins;
132 case RunningAs::RunningAsEngine:
133 return bias == LwwBias::EngineWins;
134 }
135 }
136
137 } // namespace blimp
138
139 #endif // BLIMP_NET_HELIUM_LWW_REGISTER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698