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 #include "blimp/net/helium/syncable.h" | |
| 6 | |
| 7 #include "base/macros.h" | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "testing/gmock/include/gmock/gmock.h" | |
| 10 #include "testing/gtest/include/gtest/gtest.h" | |
| 11 | |
| 12 namespace blimp { | |
| 13 namespace { | |
| 14 | |
| 15 // This is a sample implementation that demostrates the implementation | |
| 16 // of the SyncableMember and SyncableObject | |
| 17 | |
| 18 // For simplicity of this example, the ChangeSet will be an integer. | |
| 19 class IntValueSyncable : public SyncableMember<int> { | |
| 20 public: | |
| 21 explicit IntValueSyncable(SyncableObject* parent) | |
| 22 : SyncableMember(parent), value_(0) { | |
| 23 last_modified_ = parent_clock(); | |
| 24 } | |
| 25 | |
| 26 bool ModifiedSince(const VectorClock& from) override { | |
|
perumaal
2016/10/04 00:07:37
This seems backward.
The parent seems to know how
scf
2016/10/04 17:07:20
`parent::ApplyChangeset calls child::ModifiedSince
| |
| 27 return from.local_revision() < last_modified_.local_revision(); | |
| 28 } | |
| 29 | |
| 30 std::unique_ptr<int> CreateChangesetToCurrent( | |
| 31 const VectorClock& from) override { | |
| 32 return base::MakeUnique<int>(value_); | |
| 33 } | |
| 34 | |
| 35 void ApplyChangeset(const VectorClock& from, | |
| 36 const VectorClock& to, | |
| 37 std::unique_ptr<int> changeset) override { | |
| 38 // Restore the value | |
| 39 value_ = *changeset; | |
| 40 | |
| 41 // Update our clock to the latest clock | |
| 42 last_modified_ = to; | |
| 43 } | |
| 44 | |
| 45 void ReleaseCheckpointsBefore(const VectorClock& checkpoint) override { | |
| 46 last_modified_ = checkpoint; | |
| 47 } | |
| 48 | |
| 49 void SetValue(int value) { | |
| 50 value_ = value; | |
| 51 | |
| 52 // Increment the parent clock and update our last_modified_ value | |
| 53 last_modified_ = IncrementParentClock(); | |
| 54 } | |
| 55 | |
| 56 int value() { return value_; } | |
| 57 | |
| 58 private: | |
| 59 // The last time this object was changed | |
| 60 VectorClock last_modified_; | |
| 61 int32_t value_; | |
| 62 | |
| 63 DISALLOW_COPY_AND_ASSIGN(IntValueSyncable); | |
| 64 }; | |
| 65 | |
| 66 class ParentObjectSyncable : public SyncableObject { | |
| 67 public: | |
| 68 explicit ParentObjectSyncable(VectorClock clock) | |
| 69 : SyncableObject(clock), child1_(this), child2_(this) {} | |
| 70 | |
| 71 std::unique_ptr<proto::ChangesetMessage> CreateChangesetToCurrent( | |
| 72 const VectorClock& from) override { | |
| 73 std::unique_ptr<proto::ChangesetMessage> changeset = | |
| 74 base::MakeUnique<proto::ChangesetMessage>(); | |
| 75 | |
| 76 proto::TestChangesetMessage* bm = changeset->mutable_test(); | |
| 77 | |
| 78 if (child1_.ModifiedSince(from)) { | |
| 79 std::unique_ptr<int> value1 = child1_.CreateChangesetToCurrent(from); | |
| 80 bm->set_value1(*value1); | |
| 81 } | |
| 82 | |
| 83 if (child2_.ModifiedSince(from)) { | |
| 84 std::unique_ptr<int> value2 = child2_.CreateChangesetToCurrent(from); | |
| 85 bm->set_value2(*value2); | |
| 86 } | |
| 87 | |
| 88 return changeset; | |
| 89 } | |
| 90 | |
| 91 void ApplyChangeset( | |
| 92 const VectorClock& from, | |
| 93 const VectorClock& to, | |
| 94 std::unique_ptr<proto::ChangesetMessage> changeset) override { | |
| 95 proto::TestChangesetMessage bm = changeset->test(); | |
| 96 | |
| 97 int child1_value = bm.value1(); | |
| 98 if (child1_value != 0) { | |
| 99 child1_.ApplyChangeset(from, to, base::MakeUnique<int>(child1_value)); | |
| 100 } | |
| 101 | |
| 102 int child2_value = bm.value2(); | |
| 103 if (child2_value != 0) { | |
| 104 child2_.ApplyChangeset(from, to, base::MakeUnique<int>(child2_value)); | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 void ReleaseCheckpointsBefore(const VectorClock& checkpoint) override { | |
| 109 child1_.ReleaseCheckpointsBefore(checkpoint); | |
| 110 child2_.ReleaseCheckpointsBefore(checkpoint); | |
| 111 } | |
| 112 | |
| 113 IntValueSyncable& get_child1() { return child1_; } | |
| 114 IntValueSyncable& get_child2() { return child2_; } | |
| 115 | |
| 116 private: | |
| 117 IntValueSyncable child1_; | |
| 118 IntValueSyncable child2_; | |
| 119 | |
| 120 DISALLOW_COPY_AND_ASSIGN(ParentObjectSyncable); | |
| 121 }; | |
| 122 | |
| 123 class SyncableTest : public testing::Test { | |
| 124 public: | |
| 125 SyncableTest() | |
| 126 : last_sync_local_(), | |
| 127 last_sync_remote_(), | |
| 128 parent_local_(last_sync_local_), | |
| 129 parent_remote_(last_sync_remote_) {} | |
| 130 | |
| 131 ~SyncableTest() override {} | |
| 132 | |
| 133 protected: | |
| 134 VectorClock last_sync_local_; | |
| 135 VectorClock last_sync_remote_; | |
| 136 ParentObjectSyncable parent_local_; | |
| 137 ParentObjectSyncable parent_remote_; | |
| 138 | |
| 139 private: | |
| 140 DISALLOW_COPY_AND_ASSIGN(SyncableTest); | |
| 141 }; | |
| 142 | |
| 143 TEST_F(SyncableTest, CreateAndApplyChangesetTest) { | |
| 144 // Lets modify a children object | |
| 145 parent_local_.get_child1().SetValue(123); | |
| 146 | |
| 147 // At this point |child1| and |parentObject| should have its clock incremented | |
| 148 // whereas |child2| should still be the same. | |
| 149 EXPECT_TRUE(parent_local_.get_child1().ModifiedSince(last_sync_local_)); | |
| 150 EXPECT_FALSE(parent_local_.get_child2().ModifiedSince(last_sync_local_)); | |
| 151 | |
| 152 std::unique_ptr<proto::ChangesetMessage> changeset = | |
| 153 parent_local_.CreateChangesetToCurrent(last_sync_local_); | |
| 154 | |
| 155 VectorClock local_clock = parent_local_.clock(); | |
| 156 VectorClock remote_clock = local_clock.Invert(); | |
| 157 | |
| 158 parent_remote_.ApplyChangeset(last_sync_remote_, remote_clock, | |
| 159 std::move(changeset)); | |
| 160 last_sync_local_ = local_clock; | |
| 161 parent_local_.ReleaseCheckpointsBefore(local_clock); | |
| 162 EXPECT_FALSE(parent_local_.get_child1().ModifiedSince(last_sync_local_)); | |
| 163 EXPECT_FALSE(parent_local_.get_child2().ModifiedSince(last_sync_local_)); | |
| 164 | |
| 165 EXPECT_EQ(123, parent_remote_.get_child1().value()); | |
| 166 EXPECT_EQ(0, parent_remote_.get_child2().value()); | |
| 167 } | |
| 168 | |
| 169 } // namespace | |
| 170 } // namespace blimp | |
| OLD | NEW |