source: XMLIO_V2/external/src/POCO/Foundation.save/Poco/AbstractCache.h @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

  • Property svn:eol-style set to native
File size: 8.7 KB
Line 
1//
2// AbstractCache.h
3//
4// $Id: //poco/1.3/Foundation/include/Poco/AbstractCache.h#2 $
5//
6// Library: Foundation
7// Package: Cache
8// Module:  AbstractCache
9//
10// Definition of the AbstractCache class.
11//
12// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
13// and Contributors.
14//
15// Permission is hereby granted, free of charge, to any person or organization
16// obtaining a copy of the software and accompanying documentation covered by
17// this license (the "Software") to use, reproduce, display, distribute,
18// execute, and transmit the Software, and to prepare derivative works of the
19// Software, and to permit third-parties to whom the Software is furnished to
20// do so, all subject to the following:
21//
22// The copyright notices in the Software and this entire statement, including
23// the above license grant, this restriction and the following disclaimer,
24// must be included in all copies of the Software, in whole or in part, and
25// all derivative works of the Software, unless such copies or derivative
26// works are solely in the form of machine-executable object code generated by
27// a source language processor.
28//
29// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
32// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
33// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
34// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35// DEALINGS IN THE SOFTWARE.
36//
37
38
39#ifndef  Foundation_AbstractCache_INCLUDED
40#define  Foundation_AbstractCache_INCLUDED
41
42
43#include "Poco/KeyValueArgs.h"
44#include "Poco/ValidArgs.h"
45#include "Poco/Mutex.h"
46#include "Poco/Exception.h"
47#include "Poco/FIFOEvent.h"
48#include "Poco/EventArgs.h"
49#include "Poco/Delegate.h"
50#include "Poco/SharedPtr.h"
51#include <map>
52#include <set>
53#include <cstddef>
54
55
56namespace Poco {
57
58
59template <class TKey, class TValue, class TStrategy> 
60class AbstractCache
61        /// An AbstractCache is the interface of all caches.
62{
63public:
64        FIFOEvent<const KeyValueArgs<TKey, TValue > > Add;
65        FIFOEvent<const TKey>                         Remove;
66        FIFOEvent<const TKey>                         Get;
67        FIFOEvent<const EventArgs>                    Clear;
68
69        typedef std::map<TKey, SharedPtr<TValue > > DataHolder;
70        typedef typename DataHolder::iterator       Iterator;
71        typedef typename DataHolder::const_iterator ConstIterator;
72        typedef std::set<TKey>                      KeySet;
73
74        AbstractCache()
75        {
76                initialize();
77        }
78
79        AbstractCache(const TStrategy& strat): _strategy(strat)
80        {
81                initialize();
82        }
83
84        virtual ~AbstractCache()
85        {
86                uninitialize();
87        }
88
89        void add(const TKey& key, const TValue& val)
90                /// Adds the key value pair to the cache.
91                /// If for the key already an entry exists, it will be overwritten.
92        {
93                FastMutex::ScopedLock lock(_mutex);
94                doAdd(key, val);
95        }
96
97        void add(const TKey& key, SharedPtr<TValue > val)
98                /// Adds the key value pair to the cache. Note that adding a NULL SharedPtr will fail!
99                /// If for the key already an entry exists, it will be overwritten.
100        {
101                FastMutex::ScopedLock lock(_mutex);
102                doAdd(key, val);
103        }
104
105        void remove(const TKey& key)
106                /// Removes an entry from the cache. If the entry is not found,
107                /// the remove is ignored.
108        {
109                FastMutex::ScopedLock lock(_mutex);
110                Iterator it = _data.find(key);
111                doRemove(it);
112        }
113
114        bool has(const TKey& key) const
115                /// Returns true if the cache contains a value for the key.
116        {
117                FastMutex::ScopedLock lock(_mutex);
118                return doHas(key);
119        }
120
121        SharedPtr<TValue> get(const TKey& key)
122                /// Returns a SharedPtr of the value. The SharedPointer will remain valid
123                /// even when cache replacement removes the element.
124                /// If for the key no value exists, an empty SharedPtr is returned.
125        {
126                FastMutex::ScopedLock lock(_mutex);
127                return doGet (key);
128        }
129
130        void clear()
131                /// Removes all elements from the cache.
132        {
133                FastMutex::ScopedLock lock(_mutex);
134                doClear();
135        }
136
137        std::size_t size()
138                /// Returns the number of cached elements
139        {
140                FastMutex::ScopedLock lock(_mutex);
141                doReplace();
142                return _data.size();
143        }
144
145        void forceReplace()
146                /// Forces cache replacement. Note that Poco's cache strategy use for efficiency reason no background thread
147                /// which periodically triggers cache replacement. Cache Replacement is only started when the cache is modified
148                /// from outside, i.e. add is called, or when a user tries to access an cache element via get.
149                /// In some cases, i.e. expire based caching where for a long time no access to the cache happens,
150                /// it might be desirable to be able to trigger cache replacement manually.
151        {
152                FastMutex::ScopedLock lock(_mutex);
153                doReplace();
154        }
155
156        std::set<TKey> getAllKeys()
157                /// Returns a copy of all keys stored in the cache
158        {
159                FastMutex::ScopedLock lock(_mutex);
160                doReplace();
161                ConstIterator it = _data.begin();
162                ConstIterator itEnd = _data.end();
163                std::set<TKey> result;
164                for (; it != itEnd; ++it)
165                        result.insert(it->first);
166
167                return result;
168        }
169
170protected:
171        mutable FIFOEvent<ValidArgs<TKey> > IsValid;
172        mutable FIFOEvent<KeySet>           Replace;
173
174        void initialize()
175                /// Sets up event registration.
176        {
177                Add             += Delegate<TStrategy, const KeyValueArgs<TKey, TValue> >(&_strategy, &TStrategy::onAdd);
178                Remove  += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
179                Get             += Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
180                Clear   += Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
181                IsValid += Delegate<TStrategy, ValidArgs<TKey> >(&_strategy, &TStrategy::onIsValid);
182                Replace += Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
183        }
184
185        void uninitialize()
186                /// Reverts event registration.
187        {
188                Add             -= Delegate<TStrategy, const KeyValueArgs<TKey, TValue> >(&_strategy, &TStrategy::onAdd );
189                Remove  -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onRemove);
190                Get             -= Delegate<TStrategy, const TKey>(&_strategy, &TStrategy::onGet);
191                Clear   -= Delegate<TStrategy, const EventArgs>(&_strategy, &TStrategy::onClear);
192                IsValid -= Delegate<TStrategy, ValidArgs<TKey> >(&_strategy, &TStrategy::onIsValid);
193                Replace -= Delegate<TStrategy, KeySet>(&_strategy, &TStrategy::onReplace);
194        }
195
196        void doAdd(const TKey& key, const TValue& val)
197                /// Adds the key value pair to the cache.
198                /// If for the key already an entry exists, it will be overwritten.
199        {
200                Iterator it = _data.find(key);
201                doRemove(it);
202
203                KeyValueArgs<TKey, TValue> args(key, val);
204                Add.notify(this, args);
205                _data.insert(std::make_pair(key, SharedPtr<TValue>(new TValue(val))));
206               
207                doReplace();
208        }
209
210        void doAdd(const TKey& key, SharedPtr<TValue>& val)
211                /// Adds the key value pair to the cache.
212                /// If for the key already an entry exists, it will be overwritten.
213        {
214                Iterator it = _data.find(key);
215                doRemove(it);
216
217                KeyValueArgs<TKey, TValue> args(key, *val);
218                Add.notify(this, args);
219                _data.insert(std::make_pair(key, val));
220               
221                doReplace();
222        }
223
224        void doRemove(Iterator it) 
225                /// Removes an entry from the cache. If the entry is not found
226                /// the remove is ignored.
227        {
228                if (it != _data.end())
229                {
230                        Remove.notify(this, it->first);
231                        _data.erase(it);
232                }
233        }
234
235        bool doHas(const TKey& key) const
236                /// Returns true if the cache contains a value for the key
237        {
238                // ask the strategy if the key is valid
239                ConstIterator it = _data.find(key);
240                bool result = false;
241
242                if (it != _data.end())
243                {
244                        ValidArgs<TKey> args(key);
245                        IsValid.notify(this, args);
246                        result = args.isValid();
247                }
248
249                return result;
250        }
251
252        SharedPtr<TValue> doGet(const TKey& key) 
253                /// Returns a SharedPtr of the cache entry, returns 0 if for
254                /// the key no value was found
255        {
256                Iterator it = _data.find(key);
257                SharedPtr<TValue> result;
258
259                if (it != _data.end())
260                {       
261                        // inform all strategies that a read-access to an element happens
262                        Get.notify(this, key);
263                        // ask all strategies if the key is valid
264                        ValidArgs<TKey> args(key);
265                        IsValid.notify(this, args);
266
267                        if (!args.isValid())
268                        {
269                                doRemove(it);
270                        }
271                        else
272                        {
273                                result = it->second;
274                        }
275                }
276
277                return result;
278        }
279
280        void doClear()
281        {
282                static EventArgs _emptyArgs;
283                Clear.notify(this, _emptyArgs);
284                _data.clear();
285        }
286
287        void doReplace()
288        {
289                std::set<TKey> delMe;
290                Replace.notify(this, delMe);
291                // delMe contains the to be removed elements
292                typename std::set<TKey>::const_iterator it    = delMe.begin();
293                typename std::set<TKey>::const_iterator endIt = delMe.end();
294
295                for (; it != endIt; ++it)
296                {
297                        Iterator itH = _data.find(*it);
298                        doRemove(itH);
299                }
300        }
301
302        TStrategy          _strategy;
303        mutable DataHolder _data;
304        mutable FastMutex  _mutex;
305
306private:
307        AbstractCache(const AbstractCache& aCache);
308        AbstractCache& operator = (const AbstractCache& aCache);
309};
310
311
312} // namespace Poco
313
314
315#endif
Note: See TracBrowser for help on using the repository browser.