Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: sync/internal_api/public/util/proto_value_ptr.h

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 SYNC_INTERNAL_API_PUBLIC_UTIL_PROTO_VALUE_PTR_H_
6 #define SYNC_INTERNAL_API_PUBLIC_UTIL_PROTO_VALUE_PTR_H_
7
8 #include "base/gtest_prod_util.h"
9 #include "base/memory/ref_counted.h"
10
11 namespace syncer_v2 {
12 struct EntityData;
13 class ProcessorEntityTracker;
14 } // namespace syncer_v2
15
16 namespace syncer {
17
18 namespace syncable {
19 struct EntryKernel;
20 } // namespace syncable
21
22 // Default traits struct for ProtoValuePtr - adapts a
23 // ::google::protobuf::MessageLite derived type to be used with ProtoValuePtr.
24 template <typename T>
25 struct DefaultProtoValuePtrTraits {
26 // Deep copy the value from |src| to |dest|.
27 static void CopyValue(T* dest, const T& src) { dest->CopyFrom(src); }
28 // Swap the value with the source (to avoid deep copying).
29 static void SwapValue(T* dest, T* src) { dest->Swap(src); }
30 // Parse the value from BLOB.
31 static void ParseFromBlob(T* dest, const void* blob, int length) {
32 dest->ParseFromArray(blob, length);
33 }
34 // True if the |value| is a non-default value.
35 static bool HasValue(const T& value) { return value.ByteSize() > 0; }
36 // Default value for the type.
37 static const T& DefaultValue() { return T::default_instance(); }
38 };
39
40 // This is a smart pointer to a ::google::protobuf::MessageLite derived type
41 // that implements immutable, shareable, copy-on-write semantics.
42 //
43 // Additionally this class helps to avoid storing multiple copies of default
44 // instances of the wrapped type.
45 //
46 // Copying ProtoValuePtr results in ref-counted sharing of the
47 // underlying wrapper and the value contained in the wrapper.
48 //
49 // The public interface includes only immutable access to the wrapped value.
50 // The only way to assign a value to ProtoValuePtr is through a
51 // private SetValue function which is called from EntryKernel. That results
52 // in stopping sharing the previous value and creating a wrapper to the new
53 // value.
54 template <typename T, typename Traits = DefaultProtoValuePtrTraits<T>>
55 class ProtoValuePtr {
56 private:
57 // Immutable shareable ref-counted wrapper that embeds the value.
58 class Wrapper : public base::RefCountedThreadSafe<Wrapper> {
59 public:
60 explicit Wrapper(const T& value) { Traits::CopyValue(&value_, value); }
61 explicit Wrapper(T* value) { Traits::SwapValue(&value_, value); }
62
63 const T& value() const { return value_; }
64 // Create wrapper by deserializing a BLOB.
65 static Wrapper* ParseFromBlob(const void* blob, int length) {
66 Wrapper* wrapper = new Wrapper;
67 Traits::ParseFromBlob(&wrapper->value_, blob, length);
68 return wrapper;
69 }
70
71 private:
72 friend class base::RefCountedThreadSafe<Wrapper>;
73 Wrapper() {}
74 ~Wrapper() {}
75
76 T value_;
77 };
78
79 public:
80 ProtoValuePtr() {}
81 ~ProtoValuePtr() {}
82
83 const T& value() const {
84 return wrapper_ ? wrapper_->value() : Traits::DefaultValue();
85 }
86
87 const T* operator->() const {
88 const T& wrapped_instance = value();
89 return &wrapped_instance;
90 }
91
92 private:
93 friend struct syncable::EntryKernel;
94 friend struct syncer_v2::EntityData;
95 friend class syncer_v2::ProcessorEntityTracker;
96 FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, ValueAssignment);
97 FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, ValueSwap);
98 FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, SharingTest);
99 FRIEND_TEST_ALL_PREFIXES(ProtoValuePtrTest, ParsingTest);
100
101 // set the value to copy of |new_value|.
102 void set_value(const T& new_value) {
103 if (Traits::HasValue(new_value)) {
104 wrapper_ = new Wrapper(new_value);
105 } else {
106 // Don't store default value.
107 reset();
108 }
109 }
110
111 void reset() { wrapper_ = nullptr; }
112
113 // Take over |src| value (swap).
114 void swap_value(T* src) {
115 if (Traits::HasValue(*src)) {
116 wrapper_ = new Wrapper(src);
117 } else {
118 // Don't store default value.
119 reset();
120 }
121 }
122
123 void load(const void* blob, int length) {
124 wrapper_ = Wrapper::ParseFromBlob(blob, length);
125 }
126
127 scoped_refptr<Wrapper> wrapper_;
128 };
129
130 } // namespace syncer
131
132 #endif // SYNC_INTERNAL_API_PUBLIC_UTIL_PROTO_VALUE_PTR_H_
OLDNEW
« no previous file with comments | « sync/internal_api/public/util/immutable_unittest.cc ('k') | sync/internal_api/public/util/proto_value_ptr_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698