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/syncable.h" | |
| 11 #include "blimp/net/helium/syncable_common.h" | |
| 12 #include "blimp/net/helium/syncable_primitive_serializer.h" | |
| 13 #include "blimp/net/helium/version_vector.h" | |
| 14 #include "blimp/net/helium/version_vector_generator.h" | |
| 15 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h" | |
| 16 | |
| 17 namespace blimp { | |
| 18 | |
| 19 // Provides a simple syncable and atomically-writable "register" holding | |
| 20 // contents of type |RegisterType|. When there is a write conflict, it is | |
| 21 // resolved by assuming the writer indicated by |bias| has the correct value. | |
| 22 template <class RegisterType> | |
| 23 class BLIMP_NET_EXPORT LwwRegister : public Syncable { | |
| 24 public: | |
| 25 LwwRegister(VersionVectorGenerator* version_gen, | |
| 26 Bias bias, | |
| 27 RunningAs running_as); | |
| 28 ~LwwRegister() = default; | |
| 29 | |
| 30 void Set(const RegisterType& value); | |
| 31 | |
| 32 const RegisterType& value() const; | |
|
Kevin M
2016/10/17 22:19:45
Hmm. This should probably use a similar naming con
steimel
2016/10/18 23:53:20
Done.
| |
| 33 | |
| 34 // Syncable implementation. | |
| 35 bool ModifiedSince(const VersionVector& from) const override; | |
| 36 void CreateChangesetToCurrent( | |
| 37 const VersionVector& from, | |
| 38 google::protobuf::io::CodedOutputStream* output_stream) override; | |
| 39 void ApplyChangeset( | |
| 40 const VersionVector& from, | |
| 41 const VersionVector& to, | |
| 42 google::protobuf::io::CodedInputStream* input_stream) override; | |
| 43 void ReleaseCheckpointsBefore(const VersionVector& checkpoint) override; | |
| 44 | |
| 45 private: | |
| 46 VersionVectorGenerator* version_gen_; | |
| 47 VersionVector last_modified_; | |
| 48 bool locally_owned_; | |
| 49 RegisterType value_; | |
| 50 | |
| 51 DISALLOW_COPY_AND_ASSIGN(LwwRegister); | |
| 52 }; | |
| 53 | |
| 54 template <class RegisterType> | |
| 55 LwwRegister<RegisterType>::LwwRegister(VersionVectorGenerator* version_gen, | |
| 56 Bias bias, | |
| 57 RunningAs running_as) | |
| 58 : version_gen_(version_gen), last_modified_(version_gen->current()) { | |
|
Kevin M
2016/10/17 22:19:45
DCHECK(version_gen_)
Kevin M
2016/10/17 22:19:45
value_() so that it gets properly initialized to t
steimel
2016/10/18 23:53:20
Done.
| |
| 59 locally_owned_ = | |
|
Kevin M
2016/10/17 22:19:45
nit: this could be turned into an initialization l
steimel
2016/10/18 23:53:20
I thought it might be a little complex for an init
| |
| 60 ((running_as == RunningAs::Client && bias == Bias::ClientWins) || | |
| 61 (running_as == RunningAs::Engine && bias == Bias::EngineWins)); | |
| 62 } | |
| 63 | |
| 64 template <class RegisterType> | |
| 65 void LwwRegister<RegisterType>::Set(const RegisterType& value) { | |
| 66 value_ = value; | |
| 67 version_gen_->Increment(); | |
| 68 last_modified_ = last_modified_.MergeWith(version_gen_->current()); | |
| 69 } | |
| 70 | |
| 71 template <class RegisterType> | |
| 72 const RegisterType& LwwRegister<RegisterType>::value() const { | |
| 73 return value_; | |
| 74 } | |
| 75 | |
| 76 template <class RegisterType> | |
| 77 bool LwwRegister<RegisterType>::ModifiedSince(const VersionVector& from) const { | |
| 78 return from.local_revision() < last_modified_.local_revision(); | |
| 79 } | |
| 80 | |
| 81 template <class RegisterType> | |
| 82 void LwwRegister<RegisterType>::CreateChangesetToCurrent( | |
| 83 const VersionVector& from, | |
| 84 google::protobuf::io::CodedOutputStream* output_stream) { | |
| 85 SyncablePrimitiveSerializer::Serialize(value_, output_stream); | |
| 86 } | |
| 87 | |
| 88 template <class RegisterType> | |
| 89 void LwwRegister<RegisterType>::ApplyChangeset( | |
| 90 const VersionVector& from, | |
| 91 const VersionVector& to, | |
| 92 google::protobuf::io::CodedInputStream* input_stream) { | |
| 93 VersionVector::Comparison cmp = last_modified_.CompareTo(to); | |
| 94 if (cmp == VersionVector::Comparison::LessThan || | |
| 95 (cmp == VersionVector::Comparison::Conflict && !locally_owned_)) { | |
| 96 SyncablePrimitiveSerializer::Deserialize(input_stream, &value_); | |
| 97 } | |
| 98 last_modified_ = last_modified_.MergeWith(to); | |
|
scf
2016/10/17 22:09:51
do you need to merge in the case where you are not
steimel
2016/10/18 23:53:20
Well, if there's a conflict but we win, in my mind
| |
| 99 } | |
| 100 | |
| 101 template <class RegisterType> | |
| 102 void LwwRegister<RegisterType>::ReleaseCheckpointsBefore( | |
| 103 const VersionVector& checkpoint) { | |
| 104 // no-op | |
| 105 } | |
| 106 | |
| 107 } // namespace blimp | |
| 108 | |
| 109 #endif // BLIMP_NET_HELIUM_LWW_REGISTER_H_ | |
| OLD | NEW |