Line data Source code
1 :
2 : /* Copyright (c) 2007-2016, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Daniel Nachbaur <danielnachbaur@gmail.com>
4 : *
5 : * This file is part of Collage <https://github.com/Eyescale/Collage>
6 : *
7 : * This library is free software; you can redistribute it and/or modify it under
8 : * the terms of the GNU Lesser General Public License version 2.1 as published
9 : * by the Free Software Foundation.
10 : *
11 : * This library is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 : * details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with this library; if not, write to the Free Software Foundation, Inc.,
18 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : */
20 :
21 : #ifndef CO_OBJECTCM_H
22 : #define CO_OBJECTCM_H
23 :
24 : #include <co/dispatcher.h> // base class
25 : #include <co/masterCMCommand.h>
26 : #include <co/objectVersion.h> // VERSION_FOO values
27 : #include <co/types.h>
28 :
29 : //#define CO_INSTRUMENT_MULTICAST
30 : #ifdef CO_INSTRUMENT_MULTICAST
31 : #include <lunchbox/atomic.h>
32 : #endif
33 : #include <lunchbox/spinLock.h> // member
34 :
35 : namespace co
36 : {
37 : class ObjectCM;
38 : typedef lunchbox::RefPtr<ObjectCM> ObjectCMPtr;
39 :
40 : /**
41 : * @internal
42 : * The object change manager base class.
43 : *
44 : * Each object has a change manager to create and store version information.
45 : * The type of change manager depends on the object implementation, and if it is
46 : * the master object or a slave object.
47 : */
48 : class ObjectCM : public Dispatcher, public lunchbox::Referenced
49 : {
50 : public:
51 : /** Construct a new change manager. */
52 : explicit ObjectCM(Object* object);
53 :
54 : /** Destruct this change manager. */
55 : virtual ~ObjectCM();
56 :
57 : /** Initialize the change manager. */
58 : virtual void init() = 0;
59 :
60 : /** Deinitialize the change manager. */
61 : virtual void exit();
62 :
63 : /** @name Versioning */
64 : //@{
65 : /** @sa Object::push() */
66 : virtual void push(const uint128_t& groupID, const uint128_t& typeID,
67 : const Nodes& nodes);
68 :
69 : /**
70 : * Synchronize an instance to the managed object.
71 : *
72 : * @param command the command initiating the sync.
73 : * @return true if handled, false otherwise.
74 : */
75 : virtual bool sendSync(const MasterCMCommand& command);
76 :
77 : /**
78 : * Commit a new version.
79 : *
80 : * @param incarnation the commit incarnation for auto obsoletion.
81 : * @return the new head version.
82 : */
83 0 : virtual uint128_t commit(const uint32_t incarnation LB_UNUSED)
84 : {
85 0 : LBUNIMPLEMENTED;
86 0 : return VERSION_NONE;
87 : }
88 :
89 : /**
90 : * Automatically obsolete old versions.
91 : *
92 : * @param count the number of versions to retain, excluding the head
93 : * version.
94 : */
95 0 : virtual void setAutoObsolete(const uint32_t count LB_UNUSED)
96 : {
97 0 : LBUNIMPLEMENTED;
98 0 : }
99 :
100 : /** @return get the number of versions this object retains. */
101 0 : virtual uint32_t getAutoObsolete() const
102 : {
103 0 : LBUNIMPLEMENTED;
104 0 : return 0;
105 : }
106 :
107 : /**
108 : * Sync to a given version.
109 : *
110 : * @param version the version to synchronize, must be bigger than the
111 : * current version.
112 : * @return the version of the object after the operation.
113 : */
114 0 : virtual uint128_t sync(const uint128_t& version LB_UNUSED)
115 : {
116 0 : LBUNIMPLEMENTED;
117 0 : return VERSION_FIRST;
118 : }
119 :
120 : /** @return the latest available (head) version. */
121 : virtual uint128_t getHeadVersion() const = 0;
122 :
123 : /** @return the current version. */
124 : virtual uint128_t getVersion() const = 0;
125 : //@}
126 :
127 : /** @return if this object keeps instance data buffers. */
128 0 : virtual bool isBuffered() const { return false; }
129 : /** @return if this instance is the master version. */
130 : virtual bool isMaster() const = 0;
131 :
132 : /** @return the instance identifier of the master object. */
133 : virtual uint32_t getMasterInstanceID() const = 0;
134 :
135 : /** Set the master node. */
136 2 : virtual void setMasterNode(NodePtr) { /* nop */}
137 :
138 : /** @return the master node, may be 0. */
139 0 : virtual NodePtr getMasterNode() { return 0; }
140 : /**
141 : * Add a subscribed slave to the managed object.
142 : *
143 : * @param command the subscribe command initiating the add.
144 : * @return true if handled, false otherwise.
145 : */
146 : virtual bool addSlave(const MasterCMCommand& command) = 0;
147 :
148 : /**
149 : * Remove a subscribed slave.
150 : *
151 : * @param node the slave node.
152 : * @param instanceID the slave's instance identifier.
153 : */
154 0 : virtual void removeSlave(NodePtr node LB_UNUSED,
155 : const uint32_t instanceID LB_UNUSED)
156 : {
157 0 : LBUNIMPLEMENTED;
158 0 : }
159 :
160 : /** Remove all subscribed slaves from the given node. */
161 : virtual void removeSlaves(NodePtr node) = 0;
162 :
163 : /** @return the vector of current slave nodes. */
164 2 : virtual const Nodes getSlaveNodes() const { return Nodes(); }
165 : /** Apply the initial data after mapping. */
166 0 : virtual void applyMapData(const uint128_t& version LB_UNUSED)
167 : {
168 0 : LBUNIMPLEMENTED;
169 0 : }
170 :
171 : /** Add existing instance data to the object (from local node cache) */
172 0 : virtual void addInstanceDatas(const ObjectDataIStreamDeque&,
173 : const uint128_t&)
174 : {
175 0 : LBDONTCALL;
176 0 : }
177 :
178 : /** Speculatively send instance data to all nodes. */
179 0 : virtual void sendInstanceData(const Nodes&) {}
180 : /** @internal @return the object. */
181 380 : const Object* getObject() const { return _object; }
182 : /** @internal Swap the object. */
183 0 : void setObject(Object* object)
184 : {
185 0 : LBASSERT(object);
186 0 : _object = object;
187 0 : }
188 :
189 : /** The default CM for unattached objects. */
190 : static ObjectCMPtr ZERO;
191 :
192 : protected:
193 : Object* _object; //!< The managed object.
194 : lunchbox::SpinLock _lock; //!< Protects unbuffered operations on _object
195 :
196 : #ifdef CO_INSTRUMENT_MULTICAST
197 : static lunchbox::a_int32_t _hit;
198 : static lunchbox::a_int32_t _miss;
199 : #endif
200 :
201 : bool _addSlave(const MasterCMCommand& command, const uint128_t& version);
202 : virtual bool _initSlave(const MasterCMCommand& command,
203 : const uint128_t& replyVersion, bool replyUseCache);
204 : void _sendMapSuccess(const MasterCMCommand& command, const bool multicast);
205 : void _sendMapReply(const MasterCMCommand& command, const uint128_t& version,
206 : const bool result, const bool useCache,
207 : const bool multicast);
208 : void _sendEmptyVersion(const MasterCMCommand& command,
209 : const uint128_t& version, const bool multicast);
210 : };
211 : }
212 :
213 : #endif // CO_OBJECTCM_H
|