2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <folly/Function.h>
19 #include <folly/Synchronized.h>
20 #include <folly/futures/Future.h>
25 #include <unordered_set>
30 namespace observer_detail {
32 class ObserverManager;
35 * Core stores the current version of the object held by Observer. It also keeps
36 * all dependencies and dependents of the Observer.
38 class Core : public std::enable_shared_from_this<Core> {
40 using Ptr = std::shared_ptr<Core>;
41 using WeakPtr = std::weak_ptr<Core>;
44 * Blocks until creator is successfully run by ObserverManager
46 static Ptr create(folly::Function<std::shared_ptr<const void>()> creator);
49 * View of the observed object and its version
51 struct VersionedData {
54 VersionedData(std::shared_ptr<const void> data_, size_t version_)
55 : data(std::move(data_)), version(version_) {}
57 std::shared_ptr<const void> data;
62 * Gets current view of the observed object.
63 * This is safe to call from any thread. If this is called from other Observer
64 * functor then that Observer is marked as dependent on current Observer.
66 VersionedData getData();
69 * Gets the version of the observed object.
71 size_t getVersion() const {
76 * Get the last version at which the observed object was actually changed.
78 size_t getVersionLastChange() {
79 return versionLastChange_;
83 * Check if the observed object needs to be re-computed. Returns the version
84 * of last change. If force is true, re-computes the observed object, even if
85 * dependencies didn't change.
87 * This should be only called from ObserverManager thread.
89 size_t refresh(size_t version, bool force = false);
94 explicit Core(folly::Function<std::shared_ptr<const void>()> creator);
96 void addDependent(Core::WeakPtr dependent);
97 void removeStaleDependents();
99 using Dependents = std::vector<WeakPtr>;
100 using Dependencies = std::unordered_set<Ptr>;
102 folly::Synchronized<Dependents> dependents_;
103 folly::Synchronized<Dependencies> dependencies_;
105 std::atomic<size_t> version_{0};
106 std::atomic<size_t> versionLastChange_{0};
108 folly::Synchronized<VersionedData> data_;
110 folly::Function<std::shared_ptr<const void>()> creator_;
112 std::mutex refreshMutex_;
114 } // namespace observer_detail