btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / bin / bfs_tools / lib / Cache.h
blobfa3d74e19c600eee3baaffa722c14b6fc776398b
1 #ifndef CACHE_H
2 #define CACHE_H
3 /* Cache - a template cache class
4 **
5 ** Copyright 2001 pinc Software. All Rights Reserved.
6 ** Released under the terms of the MIT license.
7 */
10 #include <SupportDefs.h>
12 #include <stdio.h>
15 template<class T> class Cache
17 public:
18 class Cacheable
20 public:
21 Cacheable()
23 prev(NULL),
24 next(NULL),
25 locked(0L),
26 isDirty(false)
30 virtual ~Cacheable()
32 // perform your "undirty" work here
35 virtual bool Equals(T) = 0;
37 Cacheable *prev,*next;
38 int32 locked;
39 bool isDirty;
42 public:
43 Cache(int32 max = 20)
45 fMaxInQueue(max),
46 fCount(0),
47 fHoldChanges(false),
48 fMostRecentlyUsed(NULL),
49 fLeastRecentlyUsed(NULL)
53 virtual ~Cache()
55 Clear(0,true);
58 void Clear(int32 targetCount = 0,bool force = false)
60 Cacheable *entry = fLeastRecentlyUsed;
61 while (entry)
63 Cacheable *prev = entry->prev;
64 if (entry->locked <= 0 || force)
66 if (entry->next)
67 entry->next->prev = prev;
68 if (prev)
69 prev->next = entry->next;
71 if (fLeastRecentlyUsed == entry)
72 fLeastRecentlyUsed = prev;
73 if (fMostRecentlyUsed == entry)
74 fMostRecentlyUsed = prev;
76 delete entry;
78 if (--fCount <= targetCount)
79 break;
82 entry = prev;
86 void SetHoldChanges(bool hold)
88 fHoldChanges = hold;
89 if (!hold)
90 Clear(fMaxInQueue);
93 status_t SetDirty(T data,bool dirty)
95 Cacheable *entry = Get(data);
96 if (!entry)
97 return B_ENTRY_NOT_FOUND;
99 entry->isDirty = dirty;
100 return B_OK;
103 status_t Lock(T data)
105 Cacheable *entry = Get(data);
106 if (!entry)
107 return B_ENTRY_NOT_FOUND;
109 entry->locked++;
110 return B_OK;
113 status_t Unlock(T data)
115 Cacheable *entry = Get(data);
116 if (!entry)
117 return B_ENTRY_NOT_FOUND;
119 entry->locked--;
120 return B_OK;
123 Cacheable *Get(T data)
125 Cacheable *entry = GetFromCache(data);
126 if (entry)
128 if (fMostRecentlyUsed == entry)
129 return entry;
131 // remove entry from cache (to insert it at top of the MRU list)
132 if (entry->prev)
133 entry->prev->next = entry->next;
134 if (!entry->next)
136 if (fLeastRecentlyUsed == entry)
137 fLeastRecentlyUsed = entry->prev;
138 else
139 fprintf(stderr,"Cache: fatal error, fLeastRecentlyUsed != entry\n");
141 else
142 entry->next->prev = entry->prev;
144 else
146 entry = NewCacheable(data);
147 if (entry)
148 fCount++;
151 if (entry)
153 // insert entry at the top of the MRU list
154 entry->next = fMostRecentlyUsed;
155 entry->prev = NULL;
157 if (fMostRecentlyUsed)
158 fMostRecentlyUsed->prev = entry;
159 else if (fLeastRecentlyUsed == NULL)
160 fLeastRecentlyUsed = entry;
161 else
162 fprintf(stderr,"Cache: fatal error, fLeastRecently != NULL!\n");
163 fMostRecentlyUsed = entry;
165 // remove old nodes from of the cache (if possible and necessary)
166 if (!fHoldChanges
167 && fCount > fMaxInQueue
168 && fLeastRecentlyUsed)
169 Clear(fMaxInQueue);
171 return entry;
174 protected:
175 Cacheable *GetFromCache(T data)
177 Cacheable *entry = fMostRecentlyUsed;
178 while (entry)
180 if (entry->Equals(data))
181 return entry;
182 entry = entry->next;
184 return NULL;
187 virtual Cacheable *NewCacheable(T data) = 0;
189 int32 fMaxInQueue, fCount;
190 bool fHoldChanges;
191 Cacheable *fMostRecentlyUsed;
192 Cacheable *fLeastRecentlyUsed;
195 #endif /* CACHE_H */