Line data Source code
1 :
2 : /* Copyright (c) 2009-2014, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 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_INSTANCECACHE_H
22 : #define CO_INSTANCECACHE_H
23 :
24 : #include <co/api.h>
25 : #include <co/types.h>
26 :
27 : #include <lunchbox/clock.h> // member
28 : #include <lunchbox/lock.h> // member
29 : #include <lunchbox/lockable.h> // member
30 : #include <lunchbox/stdExt.h> // member
31 : #include <lunchbox/thread.h> // member
32 : #include <lunchbox/uint128_t.h> // member
33 :
34 : #include <iostream>
35 :
36 : namespace co
37 : {
38 : /** @internal A thread-safe cache for object instance data. */
39 : class InstanceCache
40 : {
41 : public:
42 : /** Construct a new instance cache. */
43 : CO_API explicit InstanceCache( const uint64_t maxSize = LB_100MB );
44 :
45 : /** Destruct this instance cache. */
46 : CO_API ~InstanceCache();
47 :
48 : /**
49 : * Add a new command to the instance cache.
50 : *
51 : * @param rev the object identifier and version.
52 : * @param instanceID the master instance ID.
53 : * @param command The command to add.
54 : * @param usage pre-set usage count.
55 : * @return true if the command was entered, false if not.
56 : */
57 : CO_API bool add( const ObjectVersion& rev, const uint32_t instanceID,
58 : ICommand& command, const uint32_t usage = 0 );
59 :
60 : /** Remove all items from the given node. */
61 : void remove( const NodeID& node );
62 :
63 : /** One cache entry */
64 197299 : struct Data
65 : {
66 : Data();
67 : CO_API bool operator != ( const Data& rhs ) const;
68 : CO_API bool operator == ( const Data& rhs ) const;
69 :
70 : uint32_t masterInstanceID; //!< The instance ID of the master object
71 : ObjectDataIStreamDeque versions; //!< all cached data
72 : CO_API static const Data NONE; //!< '0' return value
73 : };
74 :
75 : /**
76 : * Direct access to the cached instance data for the given object id.
77 : *
78 : * The instance data for the given object has to be released by the
79 : * caller, unless 0 has been returned. Not all returned data stream
80 : * might be ready.
81 : *
82 : * @param id the identifier of the object to look up.
83 : * @return the list of cached instance datas, or Data::NONE if no data
84 : * is cached for this object.
85 : */
86 :
87 : CO_API const Data& operator[]( const uint128_t& id );
88 :
89 : /**
90 : * Release the retrieved instance data of the given object.
91 : *
92 : * @param id the identifier of the object to release.
93 : * @param count the number of access operations to release
94 : * @return true if the element was unpinned, false if it is not in the
95 : * instance cache.
96 : */
97 : CO_API bool release( const uint128_t& id, const uint32_t count );
98 :
99 : /**
100 : * Erase all the data for the given object.
101 : *
102 : * The data does not have to be accessed, i.e., release has been called
103 : * for each previous access.
104 : *
105 : * @return true if the element was erased, false otherwise.
106 : */
107 : CO_API bool erase( const uint128_t& id );
108 :
109 : /** @return the number of bytes used by the instance cache. */
110 3 : uint64_t getSize() const { return _size; }
111 :
112 : /** @return the maximum number of bytes used by the instance cache. */
113 2 : uint64_t getMaxSize() const { return _maxSize; }
114 :
115 : /** Remove all items which are older than the given time. */
116 : void expire( const int64_t age );
117 :
118 102 : bool isEmpty() { return _items->empty(); }
119 :
120 : private:
121 197277 : struct Item
122 : {
123 : Item();
124 : Data data;
125 : unsigned used;
126 : unsigned access;
127 : NodeID from;
128 :
129 : typedef std::deque< int64_t > TimeDeque;
130 : TimeDeque times;
131 : };
132 :
133 : typedef stde::hash_map< uint128_t, Item > ItemHash;
134 : typedef ItemHash::iterator ItemHashIter;
135 : lunchbox::Lockable< ItemHash > _items;
136 :
137 : const uint64_t _maxSize; //!<high-water mark to start releasing commands
138 : uint64_t _size; //!< Current number of bytes stored
139 :
140 : const lunchbox::Clock _clock; //!< Clock for item expiration
141 :
142 : void _releaseItems( const uint32_t minUsage );
143 : void _releaseStreams( InstanceCache::Item& item );
144 : void _releaseStreams( InstanceCache::Item& item,
145 : const int64_t minTime );
146 : void _releaseFirstStream( InstanceCache::Item& item );
147 : void _deleteStream( ObjectDataIStream* iStream );
148 :
149 110 : LB_TS_VAR( _thread );
150 : };
151 :
152 : CO_API std::ostream& operator << ( std::ostream&, const InstanceCache& );
153 : }
154 : #endif //CO_INSTANCECACHE_H
|