1/*!
2  @header ECCache
3  @abstract Module of Encore
4
5  @availability OS X, GNUstep
6  @copyright 2004, 2005, 2006 Oliver Langer
7
8  Author: Oliver Langer
9
10  This library is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Lesser General Public
12  License as published by the Free Software Foundation; either
13  version 2.1 of the License, or (at your option) any later version.
14
15  This library is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  Lesser General Public License for more details.
19
20  You should have received a copy of the GNU Lesser General Public
21  License along with this library; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
23
24  <pre>
25  -------------------------------------------------------------------------
26  Modification history
27
28  24.02.05 ola     initial version
29  22.08.06 ola     license changed
30  -------------------------------------------------------------------------
31  </pre>
32*/
33
34#include <Encore/ECIterator.h>
35#include <Encore/ECCache.h>
36#include <Encore/ECArrayIterator.h>
37#include <Encore/ECCacheItem.h>
38#include <Encore/ECMemory.h>
39
40
41@implementation ECCache
42
43- init {
44  self = [super init];
45
46  self->keyToCacheItem = [[NSMutableDictionary alloc] init];
47  self->lock = [[NSLock alloc] init];
48
49  return self;
50}
51
52
53- (void) dealloc {
54  [self->keyToCacheItem release];
55  [self->lock release];
56
57  [super dealloc];
58}
59
60
61- (id) initWithCoder: (NSCoder *) decoder {
62  self = [super init];
63
64  self->keyToCacheItem = [[decoder decodeObject] retain];
65  self->lock = [[NSLock alloc] init];
66
67  return self;
68}
69
70
71- (void) encodeWithCoder: (NSCoder *) encoder {
72  [encoder encodeObject: self->keyToCacheItem];
73}
74
75
76- addObject: (id) anObject forKey: (id <NSCopying>) aKey {
77  ECCacheItem *newItem;
78
79  EC_AUTORELEASEPOOL_BEGIN
80
81  [self->lock lock];
82
83  if( [self objectExistsForKey: aKey] ) {
84    [[[ECIllegalArgumentException alloc]
85	  initWithArgumentInfo: @"Given key is already in use" ] raise];
86  }
87
88  newItem = [[ECCacheItem alloc] initWithObject: anObject ];
89  [newItem autorelease];
90  [self->keyToCacheItem setObject: newItem forKey: aKey];
91
92  [self->lock unlock];
93
94  EC_AUTORELEASEPOOL_END
95
96  return self;
97}
98
99
100- (id <ECIterator>) allKeys {
101  return [[[ECArrayIterator alloc]
102    initWithArray: [self->keyToCacheItem allKeys]] autorelease];
103}
104
105
106- (BOOL) objectExistsForKey: (id) aKey {
107  return nil != [self->keyToCacheItem objectForKey: aKey];
108}
109
110
111- objectForKey: (id) aKey incrementRefCounter: (BOOL) doIncrement {
112  ECCacheItem *item;
113  id toReturn = nil;
114
115  [self->lock lock];
116
117  item = (ECCacheItem *) [self->keyToCacheItem objectForKey: aKey];
118
119  if( nil != item ) {
120    toReturn = [item cachedObject];
121
122    if( doIncrement ) {
123      [item incrementCacheReferenceCount];
124    }
125  }
126
127  [self->lock unlock];
128
129  return toReturn;
130}
131
132
133- (unsigned int) referenceCounterOfObjectForKey: (id) aKey {
134  unsigned int toReturn;
135  ECCacheItem *item;
136
137  item = (ECCacheItem *) [self->keyToCacheItem objectForKey: aKey];
138
139  if( nil != item ) {
140    toReturn = [item cacheReferenceCount];
141  } else {
142    toReturn = 0;
143  }
144
145  return toReturn;
146}
147
148
149- (void) decrementRefCounterForKey: (id) aKey {
150  ECCacheItem *item;
151
152  [self->lock lock];
153
154  item = (ECCacheItem *) [self->keyToCacheItem objectForKey: aKey];
155
156  if( nil != item ) {
157    [item decrementCacheReferenceCount];
158	if( [item cacheReferenceCount] < 1 ) {
159	  [self->keyToCacheItem removeObjectForKey: aKey];
160	}
161  }
162
163  [self->lock unlock];
164}
165
166
167- (void) removeObjectForKey: (id) aKey {
168  ECCacheItem *item;
169
170  [self->lock lock];
171
172  item = (ECCacheItem *) [self->keyToCacheItem objectForKey: aKey];
173  if( nil != item ) {
174    [self->keyToCacheItem removeObjectForKey: aKey];
175  }
176
177  [self->lock unlock];
178}
179@end
180