Chromium Code Reviews| OLD | NEW |
|---|---|
| (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_ | |
| OLD | NEW |