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/net/blimp_net_export.h" | |
| 10 #include "blimp/net/helium/bias.h" | |
| 11 #include "blimp/net/helium/running_as.h" | |
| 12 #include "blimp/net/helium/syncable.h" | |
| 13 #include "blimp/net/helium/syncable_primitive_serializer.h" | |
| 14 #include "blimp/net/helium/version_vector.h" | |
| 15 #include "blimp/net/helium/version_vector_generator.h" | |
| 16 #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite .h" | |
| 17 | |
| 18 namespace blimp { | |
| 19 | |
| 20 // Provides a simple syncable and atomically-writable "register" holding | |
| 21 // contents of type |RegisterType|. When there is a write conflict, it is | |
| 22 // resolved by assuming the writer indicated by |bias| has the correct value. | |
| 23 template <class RegisterType, Bias bias> | |
| 24 class BLIMP_NET_EXPORT LwwRegister : public Syncable { | |
| 25 public: | |
| 26 LwwRegister(VersionVectorGenerator* version_gen, RunningAs running_as); | |
| 27 ~LwwRegister() = default; | |
| 28 | |
| 29 void Set(const RegisterType& value); | |
|
Kevin M
2016/10/13 22:03:36
"set_value()" would also work.
steimel
2016/10/17 21:45:59
Acknowledged.
| |
| 30 | |
| 31 const RegisterType& get() const; | |
|
Kevin M
2016/10/13 22:03:36
"Get()", or "value()".
steimel
2016/10/17 21:45:59
Done.
| |
| 32 | |
| 33 // Syncable implementation. | |
| 34 bool ModifiedSince(const VersionVector& from) const override; | |
| 35 void CreateChangesetToCurrent( | |
| 36 const VersionVector& from, | |
| 37 google::protobuf::io::ZeroCopyOutputStream* output_stream) override; | |
| 38 void ApplyChangeset( | |
| 39 const VersionVector& from, | |
| 40 const VersionVector& to, | |
| 41 google::protobuf::io::ZeroCopyInputStream* input_stream) override; | |
| 42 void ReleaseCheckpointsBefore(const VersionVector& checkpoint) override; | |
| 43 | |
| 44 private: | |
| 45 VersionVectorGenerator* version_gen_; | |
| 46 VersionVector last_modified_; | |
| 47 RunningAs running_as_; | |
| 48 RegisterType value_; | |
| 49 | |
| 50 bool LocalWinsConflict() const; | |
| 51 | |
| 52 DISALLOW_COPY_AND_ASSIGN(LwwRegister); | |
| 53 }; | |
| 54 | |
| 55 template <class RegisterType, Bias bias> | |
| 56 LwwRegister<RegisterType, bias>::LwwRegister( | |
| 57 VersionVectorGenerator* version_gen, | |
| 58 RunningAs running_as) | |
| 59 : version_gen_(version_gen), | |
| 60 last_modified_(version_gen->current()), | |
| 61 running_as_(running_as) {} | |
| 62 | |
| 63 template <class RegisterType, Bias bias> | |
| 64 void LwwRegister<RegisterType, bias>::Set(const RegisterType& value) { | |
| 65 value_ = value; | |
| 66 version_gen_->Increment(); | |
| 67 last_modified_ = last_modified_.MergeWith(version_gen_->current()); | |
| 68 } | |
| 69 | |
| 70 template <class RegisterType, Bias bias> | |
| 71 const RegisterType& LwwRegister<RegisterType, bias>::get() const { | |
| 72 return value_; | |
| 73 } | |
| 74 | |
| 75 template <class RegisterType, Bias bias> | |
| 76 bool LwwRegister<RegisterType, bias>::ModifiedSince( | |
| 77 const VersionVector& from) const { | |
| 78 return from.local_revision() < last_modified_.local_revision(); | |
| 79 } | |
| 80 | |
| 81 template <class RegisterType, Bias bias> | |
| 82 void LwwRegister<RegisterType, bias>::CreateChangesetToCurrent( | |
| 83 const VersionVector& from, | |
| 84 google::protobuf::io::ZeroCopyOutputStream* output_stream) { | |
| 85 SyncablePrimitiveSerializer<RegisterType>::SerializeSyncablePrimitive( | |
| 86 value_, output_stream); | |
| 87 } | |
| 88 | |
| 89 template <class RegisterType, Bias bias> | |
| 90 void LwwRegister<RegisterType, bias>::ApplyChangeset( | |
| 91 const VersionVector& from, | |
| 92 const VersionVector& to, | |
| 93 google::protobuf::io::ZeroCopyInputStream* input_stream) { | |
| 94 VersionVector::Comparison cmp = last_modified_.CompareTo(to); | |
| 95 if (cmp == VersionVector::Comparison::LessThan || | |
| 96 (cmp == VersionVector::Comparison::Conflict && !LocalWinsConflict())) { | |
| 97 SyncablePrimitiveSerializer<RegisterType>::DeserializeSyncablePrimitive( | |
| 98 value_, input_stream); | |
| 99 } | |
| 100 last_modified_ = last_modified_.MergeWith(to); | |
| 101 } | |
| 102 | |
| 103 template <class RegisterType, Bias bias> | |
| 104 void LwwRegister<RegisterType, bias>::ReleaseCheckpointsBefore( | |
| 105 const VersionVector& checkpoint) { | |
| 106 // no-op | |
| 107 } | |
| 108 | |
| 109 template <class RegisterType, Bias bias> | |
| 110 bool LwwRegister<RegisterType, bias>::LocalWinsConflict() const { | |
|
Kevin M
2016/10/13 22:03:36
Two cases = this should probably be an if/elseif.
Kevin M
2016/10/13 22:49:55
Can we just precompute this in the constructor, e.
steimel
2016/10/17 21:45:59
Done.
| |
| 111 switch (running_as_) { | |
| 112 case RunningAs::Client: | |
| 113 return bias == Bias::ClientWins; | |
| 114 case RunningAs::Engine: | |
| 115 return bias == Bias::EngineWins; | |
| 116 } | |
| 117 } | |
| 118 | |
| 119 } // namespace blimp | |
| 120 | |
| 121 #endif // BLIMP_NET_HELIUM_LWW_REGISTER_H_ | |
| OLD | NEW |