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_HELIUM_LWW_REGISTER_H_ | |
| 6 #define BLIMP_HELIUM_LWW_REGISTER_H_ | |
| 7 | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "blimp/helium/blimp_helium_export.h" | |
| 10 #include "blimp/helium/syncable.h" | |
| 11 #include "blimp/helium/syncable_common.h" | |
| 12 #include "blimp/helium/syncable_primitive_serializer.h" | |
| 13 #include "blimp/helium/version_vector.h" | |
| 14 #include "blimp/helium/version_vector_generator.h" | |
| 15 #include "third_party/protobuf/src/google/protobuf/io/coded_stream.h" | |
| 16 | |
| 17 namespace blimp { | |
| 18 namespace helium { | |
| 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> | |
| 24 class BLIMP_HELIUM_EXPORT LwwRegister : public Syncable { | |
| 25 public: | |
| 26 LwwRegister(VersionVectorGenerator* version_gen, | |
| 27 Bias bias, | |
| 28 RunningAs running_as); | |
| 29 ~LwwRegister() = default; | |
| 30 | |
| 31 void Set(const RegisterType& value); | |
| 32 | |
| 33 const RegisterType& Get() const; | |
| 34 | |
| 35 // Syncable implementation. | |
| 36 bool ModifiedSince(const VersionVector& from) const override; | |
| 37 void CreateChangesetToCurrent( | |
| 38 const VersionVector& from, | |
| 39 google::protobuf::io::CodedOutputStream* output_stream) override; | |
| 40 void ApplyChangeset( | |
| 41 const VersionVector& from, | |
| 42 const VersionVector& to, | |
| 43 google::protobuf::io::CodedInputStream* input_stream) override; | |
| 44 void ReleaseCheckpointsBefore(const VersionVector& checkpoint) override; | |
| 45 | |
| 46 private: | |
| 47 VersionVectorGenerator* version_gen_; | |
| 48 VersionVector last_modified_; | |
| 49 bool locally_owned_; | |
| 50 RegisterType value_; | |
| 51 bool value_set_; | |
|
Kevin M
2016/10/19 00:27:08
Suggestion: you can use an inline initializer here
steimel
2016/10/19 16:40:49
Done.
| |
| 52 | |
| 53 DISALLOW_COPY_AND_ASSIGN(LwwRegister); | |
| 54 }; | |
| 55 | |
| 56 template <class RegisterType> | |
| 57 LwwRegister<RegisterType>::LwwRegister(VersionVectorGenerator* version_gen, | |
| 58 Bias bias, | |
| 59 RunningAs running_as) | |
| 60 : version_gen_(version_gen), | |
| 61 last_modified_(version_gen->current()), | |
| 62 value_set_(false) { | |
| 63 DCHECK(version_gen_); | |
| 64 locally_owned_ = ((running_as == RunningAs::Client && bias == Bias::Client) || | |
| 65 (running_as == RunningAs::Engine && bias == Bias::Engine)); | |
| 66 } | |
| 67 | |
| 68 template <class RegisterType> | |
| 69 void LwwRegister<RegisterType>::Set(const RegisterType& value) { | |
| 70 value_ = value; | |
| 71 value_set_ = true; | |
| 72 version_gen_->Increment(); | |
| 73 last_modified_ = last_modified_.MergeWith(version_gen_->current()); | |
| 74 } | |
| 75 | |
| 76 template <class RegisterType> | |
| 77 const RegisterType& LwwRegister<RegisterType>::Get() const { | |
| 78 DCHECK(value_set_); | |
| 79 return value_; | |
| 80 } | |
| 81 | |
| 82 template <class RegisterType> | |
| 83 bool LwwRegister<RegisterType>::ModifiedSince(const VersionVector& from) const { | |
| 84 return from.local_revision() < last_modified_.local_revision(); | |
| 85 } | |
| 86 | |
| 87 template <class RegisterType> | |
| 88 void LwwRegister<RegisterType>::CreateChangesetToCurrent( | |
| 89 const VersionVector& from, | |
| 90 google::protobuf::io::CodedOutputStream* output_stream) { | |
| 91 SyncablePrimitiveSerializer::Serialize(value_, output_stream); | |
| 92 } | |
| 93 | |
| 94 template <class RegisterType> | |
| 95 void LwwRegister<RegisterType>::ApplyChangeset( | |
| 96 const VersionVector& from, | |
| 97 const VersionVector& to, | |
| 98 google::protobuf::io::CodedInputStream* input_stream) { | |
| 99 VersionVector::Comparison cmp = last_modified_.CompareTo(to); | |
| 100 if (cmp == VersionVector::Comparison::LessThan || | |
| 101 (cmp == VersionVector::Comparison::Conflict && !locally_owned_)) { | |
| 102 // TODO(steimel): deal with Deserialize returning false once ApplyChangeset | |
| 103 // returns a HeliumResult. | |
| 104 SyncablePrimitiveSerializer::Deserialize(input_stream, &value_); | |
| 105 value_set_ = true; | |
| 106 } | |
| 107 last_modified_ = last_modified_.MergeWith(to); | |
| 108 } | |
| 109 | |
| 110 template <class RegisterType> | |
| 111 void LwwRegister<RegisterType>::ReleaseCheckpointsBefore( | |
| 112 const VersionVector& checkpoint) { | |
| 113 // no-op | |
| 114 } | |
| 115 | |
| 116 } // namespace helium | |
| 117 } // namespace blimp | |
| 118 | |
| 119 #endif // BLIMP_HELIUM_LWW_REGISTER_H_ | |
| OLD | NEW |