Line data Source code
1 :
2 : /* Copyright (c) 2007-2014, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2011-2012, 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 : 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 0 : { LBUNIMPLEMENTED; return VERSION_NONE; }
85 :
86 : /**
87 : * Automatically obsolete old versions.
88 : *
89 : * @param count the number of versions to retain, excluding the head
90 : * version.
91 : */
92 0 : virtual void setAutoObsolete( const uint32_t count LB_UNUSED )
93 0 : { LBUNIMPLEMENTED; }
94 :
95 : /** @return get the number of versions this object retains. */
96 0 : virtual uint32_t getAutoObsolete() const { LBUNIMPLEMENTED; return 0; }
97 :
98 : /**
99 : * Sync to a given version.
100 : *
101 : * @param version the version to synchronize, must be bigger than the
102 : * current version.
103 : * @return the version of the object after the operation.
104 : */
105 0 : virtual uint128_t sync( const uint128_t& version LB_UNUSED )
106 0 : { LBUNIMPLEMENTED; return VERSION_FIRST; }
107 :
108 : /** @return the latest available (head) version. */
109 : virtual uint128_t getHeadVersion() const = 0;
110 :
111 : /** @return the current version. */
112 : virtual uint128_t getVersion() const = 0;
113 : //@}
114 :
115 : /** @return if this object keeps instance data buffers. */
116 0 : virtual bool isBuffered() const{ return false; }
117 :
118 : /** @return if this instance is the master version. */
119 : virtual bool isMaster() const = 0;
120 :
121 : /** @return the instance identifier of the master object. */
122 : virtual uint32_t getMasterInstanceID() const = 0;
123 :
124 : /** Set the master node. */
125 8 : virtual void setMasterNode( NodePtr ) { /* nop */ }
126 :
127 : /** @return the master node, may be 0. */
128 0 : virtual NodePtr getMasterNode() { return 0; }
129 :
130 : /**
131 : * Add a subscribed slave to the managed object.
132 : *
133 : * @param command the subscribe command initiating the add.
134 : * @return true if handled, false otherwise.
135 : */
136 : virtual bool addSlave( const MasterCMCommand& command ) = 0;
137 :
138 : /**
139 : * Remove a subscribed slave.
140 : *
141 : * @param node the slave node.
142 : * @param instanceID the slave's instance identifier.
143 : */
144 0 : virtual void removeSlave( NodePtr node LB_UNUSED,
145 : const uint32_t instanceID LB_UNUSED )
146 0 : { LBUNIMPLEMENTED; }
147 :
148 : /** Remove all subscribed slaves from the given node. */
149 : virtual void removeSlaves( NodePtr node ) = 0;
150 :
151 : /** @return the vector of current slave nodes. */
152 8 : virtual const Nodes getSlaveNodes() const { return Nodes(); }
153 :
154 : /** Apply the initial data after mapping. */
155 0 : virtual void applyMapData( const uint128_t& version LB_UNUSED )
156 0 : { LBUNIMPLEMENTED; }
157 :
158 : /** Add existing instance data to the object (from local node cache) */
159 0 : virtual void addInstanceDatas( const ObjectDataIStreamDeque&,
160 : const uint128_t& )
161 0 : { LBDONTCALL; }
162 :
163 : /** Speculatively send instance data to all nodes. */
164 0 : virtual void sendInstanceData( Nodes& ){}
165 :
166 : /** @internal @return the object. */
167 395 : const Object* getObject( ) const { return _object; }
168 :
169 : /** @internal Swap the object. */
170 0 : void setObject( Object* object )
171 0 : { LBASSERT( object ); _object = object; }
172 :
173 : /** The default CM for unattached objects. */
174 : static ObjectCMPtr ZERO;
175 :
176 : protected:
177 : Object* _object; //!< The managed object.
178 : lunchbox::SpinLock _lock; //!< Protects unbuffered operations on _object
179 :
180 : #ifdef CO_INSTRUMENT_MULTICAST
181 : static lunchbox::a_int32_t _hit;
182 : static lunchbox::a_int32_t _miss;
183 : #endif
184 :
185 : bool _addSlave( const MasterCMCommand& command, const uint128_t& version );
186 : virtual bool _initSlave( const MasterCMCommand& command,
187 : const uint128_t& replyVersion,
188 : bool replyUseCache );
189 : void _sendMapSuccess( const MasterCMCommand& command,
190 : const bool multicast );
191 : void _sendMapReply( const MasterCMCommand& command,
192 : const uint128_t& version, const bool result,
193 : const bool useCache, const bool multicast );
194 : void _sendEmptyVersion( const MasterCMCommand& command,
195 : const uint128_t& version, const bool multicast);
196 : };
197 : }
198 :
199 : #endif // CO_OBJECTCM_H
|