summaryrefslogtreecommitdiffstats
path: root/sync/syncable
diff options
context:
space:
mode:
authormaxbogue <maxbogue@chromium.org>2015-10-29 11:39:19 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-29 18:40:28 +0000
commit95e33335f64bff190d67d8958a3ffac701f6da6f (patch)
tree3e50077e0b59ee1bbe4b79e380308c29708023a4 /sync/syncable
parent68cfb908f4a01b95b64eac573825325dd7bdf55d (diff)
downloadchromium_src-95e33335f64bff190d67d8958a3ffac701f6da6f.zip
chromium_src-95e33335f64bff190d67d8958a3ffac701f6da6f.tar.gz
chromium_src-95e33335f64bff190d67d8958a3ffac701f6da6f.tar.bz2
[Sync] Introduce EntityData and EntityMetadata.
BUG=536895 Review URL: https://codereview.chromium.org/1421663004 Cr-Commit-Position: refs/heads/master@{#356899}
Diffstat (limited to 'sync/syncable')
-rw-r--r--sync/syncable/entry_kernel.h2
-rw-r--r--sync/syncable/proto_value_ptr.h110
-rw-r--r--sync/syncable/proto_value_ptr_unittest.cc208
3 files changed, 1 insertions, 319 deletions
diff --git a/sync/syncable/entry_kernel.h b/sync/syncable/entry_kernel.h
index c1fc5e5..4e901ce 100644
--- a/sync/syncable/entry_kernel.h
+++ b/sync/syncable/entry_kernel.h
@@ -13,8 +13,8 @@
#include "sync/internal_api/public/base/model_type.h"
#include "sync/internal_api/public/base/unique_position.h"
#include "sync/internal_api/public/util/immutable.h"
+#include "sync/internal_api/public/util/proto_value_ptr.h"
#include "sync/syncable/metahandle_set.h"
-#include "sync/syncable/proto_value_ptr.h"
#include "sync/syncable/syncable_id.h"
#include "sync/util/time.h"
diff --git a/sync/syncable/proto_value_ptr.h b/sync/syncable/proto_value_ptr.h
deleted file mode 100644
index dea3a68..0000000
--- a/sync/syncable/proto_value_ptr.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef SYNC_SYNCABLE_ENTRY_PROTO_FIELD_PTR_H_
-#define SYNC_SYNCABLE_ENTRY_PROTO_FIELD_PTR_H_
-
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "sync/protocol/attachments.pb.h"
-#include "sync/protocol/sync.pb.h"
-
-namespace syncer {
-namespace syncable {
-
-// Default traits struct for ProtoValuePtr - adapts a
-// ::google::protobuf::MessageLite derived type to be used with ProtoValuePtr.
-template <typename T>
-struct DefaultProtoValuePtrTraits {
- // Deep copy the value from |src| to |dest|.
- static void CopyValue(T* dest, const T& src) { dest->CopyFrom(src); }
- // Parse the value from BLOB.
- static void ParseFromBlob(T* dest, const void* blob, int length) {
- dest->ParseFromArray(blob, length);
- }
- // True if the |value| is a non-default value.
- static bool HasValue(const T& value) { return value.ByteSize() > 0; }
- // Default value for the type.
- static const T& DefaultValue() { return T::default_instance(); }
-};
-
-// This is a smart pointer to a ::google::protobuf::MessageLite derived type
-// that implements immutable, shareable, copy-on-write semantics.
-//
-// Additionally this class helps to avoid storing multiple copies of default
-// instances of the wrapped type.
-//
-// Copying ProtoValuePtr results in ref-counted sharing of the
-// underlying wrapper and the value contained in the wrapper.
-//
-// The public interface includes only immutable access to the wrapped value.
-// The only way to assign a value to ProtoValuePtr is through a
-// private SetValue function which is called from EntryKernel. That results
-// in stopping sharing the previous value and creating a wrapper to the new
-// value.
-template <typename T, typename Traits = DefaultProtoValuePtrTraits<T>>
-class ProtoValuePtr {
- private:
- // Immutable shareable ref-counted wrapper that embeds the value.
- class Wrapper : public base::RefCountedThreadSafe<Wrapper> {
- public:
- Wrapper(const T& value) { Traits::CopyValue(&value_, value); }
- const T& value() const { return value_; }
- // Create wrapper by deserializing a BLOB.
- static Wrapper* ParseFromBlob(const void* blob, int length) {
- Wrapper* wrapper = new Wrapper;
- Traits::ParseFromBlob(&wrapper->value_, blob, length);
- return wrapper;
- }
-
- private:
- friend class base::RefCountedThreadSafe<Wrapper>;
- Wrapper() {}
- ~Wrapper() {}
-
- T value_;
- };
-
- ProtoValuePtr() {}
- ~ProtoValuePtr() {}
-
- public:
- const T& value() const {
- return wrapper_ ? wrapper_->value() : Traits::DefaultValue();
- }
-
- const T* operator->() const {
- const T& wrapped_instance = value();
- return &wrapped_instance;
- }
-
- private:
- friend struct EntryKernel;
- FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, BasicTest);
- FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, SharingTest);
- FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, ParsingTest);
-
- void set_value(const T& new_value) {
- if (Traits::HasValue(new_value)) {
- wrapper_ = new Wrapper(new_value);
- } else {
- // Don't store default value.
- wrapper_ = nullptr;
- }
- }
-
- void load(const void* blob, int length) {
- wrapper_ = Wrapper::ParseFromBlob(blob, length);
- }
-
- scoped_refptr<Wrapper> wrapper_;
-};
-
-typedef ProtoValuePtr<sync_pb::EntitySpecifics> EntitySpecificsPtr;
-typedef ProtoValuePtr<sync_pb::AttachmentMetadata> AttachmentMetadataPtr;
-
-} // namespace syncable
-} // namespace syncer
-
-#endif // SYNC_SYNCABLE_ENTRY_PROTO_FIELD_PTR_H_
diff --git a/sync/syncable/proto_value_ptr_unittest.cc b/sync/syncable/proto_value_ptr_unittest.cc
deleted file mode 100644
index 4686286c6..0000000
--- a/sync/syncable/proto_value_ptr_unittest.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "sync/syncable/proto_value_ptr.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace syncer {
-namespace syncable {
-
-namespace {
-
-// TestValue class is used as a template argument with ProtoValuePtr<T>
-class TestValue {
- public:
- TestValue() : value_(0), is_initialized_(false), is_default_(false) {}
- explicit TestValue(int value)
- : value_(value), is_initialized_(true), is_default_(false) {}
-
- ~TestValue() { g_delete_count++; }
-
- static void ResetCounters() {
- g_copy_count = 0;
- g_parse_count = 0;
- g_delete_count = 0;
- }
-
- static int copy_count() { return g_copy_count; }
- static int parse_count() { return g_parse_count; }
- static int delete_count() { return g_delete_count; }
-
- int value() const { return value_; }
- bool is_initialized() const { return is_initialized_; }
- bool is_default() const { return is_default_; }
-
- // TestValue uses the default traits struct with ProtoValuePtr<TestValue>.
- // The following 4 functions are expected by the traits struct to exist
- // in this class.
- void CopyFrom(const TestValue& from) {
- // Expected to always copy from an initialized instance
- // to an uninitialized one.
- // Not expected either value to be default.
- ASSERT_FALSE(is_initialized());
- ASSERT_FALSE(is_default());
- ASSERT_TRUE(from.is_initialized());
- ASSERT_FALSE(from.is_default());
- value_ = from.value();
- is_initialized_ = true;
- g_copy_count++;
- }
-
- void ParseFromArray(const void* blob, int length) {
- // Similarly to CopyFrom this is expected to be called on
- // an uninitialized instance.
- ASSERT_FALSE(is_initialized());
- ASSERT_FALSE(is_default());
- // The blob is an address of an integer
- ASSERT_EQ(static_cast<int>(sizeof(int)), length);
- value_ = *static_cast<const int*>(blob);
- is_initialized_ = true;
- g_parse_count++;
- }
-
- int ByteSize() const { return is_initialized() ? sizeof(int) : 0; }
-
- static const TestValue& default_instance() {
- static TestValue default_instance;
- default_instance.is_default_ = true;
- return default_instance;
- }
-
- private:
- static int g_copy_count;
- static int g_parse_count;
- static int g_delete_count;
-
- int value_;
- bool is_initialized_;
- bool is_default_;
-
- DISALLOW_COPY_AND_ASSIGN(TestValue);
-};
-
-// Static initializers.
-int TestValue::g_copy_count = 0;
-int TestValue::g_parse_count = 0;
-int TestValue::g_delete_count = 0;
-
-} // namespace
-
-typedef ProtoValuePtr<TestValue> TestPtr;
-
-class ProtoValuePtrTest : public testing::Test {
- public:
- void SetUp() override { TestValue::ResetCounters(); }
-
- static bool WrappedValuesAreShared(const TestPtr& ptr1, const TestPtr& ptr2) {
- const TestValue& wrapped_value_1 = ptr1.value();
- const TestValue& wrapped_value_2 = ptr2.value();
- // Compare addresses.
- return &wrapped_value_1 == &wrapped_value_2;
- }
-};
-
-TEST_F(ProtoValuePtrTest, BasicTest) {
- // Basic assignment and default value.
- TestValue t1(1);
- {
- TestPtr ptr1;
- EXPECT_TRUE(ptr1->is_default());
-
- ptr1.set_value(t1);
- EXPECT_FALSE(ptr1->is_default());
- EXPECT_EQ(1, ptr1->value());
- }
-
- EXPECT_EQ(1, TestValue::copy_count());
- EXPECT_EQ(1, TestValue::delete_count());
-}
-
-TEST_F(ProtoValuePtrTest, SharingTest) {
- // Sharing between two pointers.
- TestValue empty;
- TestValue t2(2);
- TestValue t3(3);
- {
- TestPtr ptr2;
- TestPtr ptr3;
-
- EXPECT_TRUE(ptr2->is_default());
- EXPECT_TRUE(ptr3->is_default());
- EXPECT_EQ(0, TestValue::copy_count());
- EXPECT_EQ(0, TestValue::delete_count());
-
- ptr2.set_value(t2);
- EXPECT_EQ(1, TestValue::copy_count());
- EXPECT_EQ(0, TestValue::delete_count());
-
- ptr3 = ptr2;
- // Both |ptr2| and |ptr3| now share the same value "2".
- // No additional copies expected.
- EXPECT_EQ(1, TestValue::copy_count());
- EXPECT_EQ(0, TestValue::delete_count());
- EXPECT_FALSE(ptr3->is_default());
- EXPECT_EQ(2, ptr3->value());
- EXPECT_TRUE(WrappedValuesAreShared(ptr2, ptr3));
-
- // Stop sharing - |ptr2| is "3" and |ptr3| is still "2".
- ptr2.set_value(t3);
- EXPECT_FALSE(WrappedValuesAreShared(ptr2, ptr3));
- EXPECT_EQ(3, ptr2->value());
- EXPECT_EQ(2, ptr3->value());
- // No extra copies or deletions expected.
- EXPECT_EQ(2, TestValue::copy_count());
- EXPECT_EQ(0, TestValue::delete_count());
-
- // |ptr3| still has the old value.
- EXPECT_EQ(2, ptr3->value());
-
- // Share again. Both values are "3".
- ptr3 = ptr2;
- EXPECT_EQ(3, ptr3->value());
- // This should have resulted in deleting the wrapper for the value "2".
- EXPECT_EQ(1, TestValue::delete_count());
- // No extra copies expected.
- EXPECT_EQ(2, TestValue::copy_count());
-
- // Set default value to one of the pointers.
- ptr2.set_value(empty);
- EXPECT_TRUE(ptr2->is_default());
- // The other one is still intact.
- EXPECT_FALSE(ptr3->is_default());
- EXPECT_EQ(3, ptr3->value());
- // No extra copies or deletions expected.
- EXPECT_EQ(1, TestValue::delete_count());
- EXPECT_EQ(2, TestValue::copy_count());
-
- // Copy the default value between the pointers.
- ptr3 = ptr2;
- EXPECT_TRUE(ptr3->is_default());
- // The wrapper for "3" is now deleted.
- EXPECT_EQ(2, TestValue::delete_count());
- }
-
- // No extra deletions expected upon leaving the scope.
- EXPECT_EQ(2, TestValue::delete_count());
-}
-
-TEST_F(ProtoValuePtrTest, ParsingTest) {
- int v1 = 21;
-
- {
- TestPtr ptr1;
-
- ptr1.load(&v1, sizeof(int));
-
- EXPECT_EQ(1, TestValue::parse_count());
- EXPECT_EQ(0, TestValue::copy_count());
-
- EXPECT_EQ(v1, ptr1->value());
- }
-
- EXPECT_EQ(1, TestValue::delete_count());
-}
-
-} // namespace syncable
-} // namespace syncer