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