]> err.no Git - scalable-opengroupware.org/blob - SoObjects/SOGo/SOGoLRUCache.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1086 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / SOGo / SOGoLRUCache.m
1 /*
2  Copyright (C) 2000-2004 SKYRIX Software AG
3  
4  This file is part of OGo
5  
6  OGo is free software; you can redistribute it and/or modify it under
7  the terms of the GNU Lesser General Public License as published by the
8  Free Software Foundation; either version 2, or (at your option) any
9  later version.
10  
11  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12  WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14  License for more details.
15  
16  You should have received a copy of the GNU Lesser General Public
17  License along with OGo; see the file COPYING.  If not, write to the
18  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19  02111-1307, USA.
20  */
21
22 #include "SOGoLRUCache.h"
23 #include "common.h"
24
25 @interface SOGoLRUCacheItem : NSObject
26 {
27   id object;
28   unsigned useCount;
29 }
30
31 - (id)initWithObject:(id)_obj;
32 - (id)object;
33
34 - (unsigned)useCount;
35
36 @end
37
38 @implementation SOGoLRUCacheItem
39
40 - (id)initWithObject:(id)_obj {
41   self = [super init];
42   if(self) {
43     ASSIGN(self->object, _obj);
44     self->useCount = 1;
45   }
46   return self;
47 }
48
49 - (id)object {
50   self->useCount++;
51   return self->object;
52 }
53
54 - (unsigned)useCount {
55   return self->useCount;
56 }
57
58 @end
59
60 @implementation SOGoLRUCache
61
62 - (id)initWithCacheSize:(unsigned)_size {
63   self = [super init];
64   if(self) {
65     self->size = _size;
66     self->entries = [[NSMutableDictionary alloc] initWithCapacity:_size];
67   }
68   return self;
69 }
70
71 - (void)dealloc {
72   [self->entries release];
73   [super dealloc];
74 }
75
76 - (void)addObject:(id)_obj forKey:(id)_key {
77   SOGoLRUCacheItem *item;
78   
79   NSAssert(_obj, @"Attempt to insert nil object!");
80   
81   if([self->entries count] >= self->size) {
82     /* need to find minimum and get rid of it */
83     NSEnumerator     *keyEnum;
84     SOGoLRUCacheItem *item;
85     id               key, leastUsedItemKey;
86     unsigned         minimumUseCount = INT_MAX;
87     
88     keyEnum = [self->entries keyEnumerator];
89     while((key = [keyEnum nextObject])) {
90       item = [self->entries objectForKey:key];
91       if([item useCount] < minimumUseCount) {
92         minimumUseCount = [item useCount];
93         leastUsedItemKey = key;
94       }
95     }
96     [self->entries removeObjectForKey:leastUsedItemKey];
97   }
98   item = [[SOGoLRUCacheItem alloc] initWithObject:_obj];
99   [self->entries setObject:item forKey:_key];
100   [item release];
101 }
102
103 - (id)objectForKey:(id)_key {
104   SOGoLRUCacheItem *item;
105   
106   item = [self->entries objectForKey:_key];
107   if(!item)
108     return nil;
109   return [item object];
110 }
111
112 @end