remove header text:
[blender.git] / intern / memutil / intern / MEM_CacheLimiterC-Api.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Peter Schlaile <peter@schlaile.de> 2005
19  *
20  * ***** BEGIN GPL LICENSE BLOCK *****
21  */
22
23 /** \file memutil/intern/MEM_CacheLimiterC-Api.cpp
24  *  \ingroup memutil
25  */
26
27 #include <cstddef>
28
29 #include "MEM_CacheLimiter.h"
30 #include "MEM_CacheLimiterC-Api.h"
31
32 static intptr_t & get_max() 
33 {
34         static intptr_t m = 32*1024*1024;
35         return m;
36 }
37
38 void MEM_CacheLimiter_set_maximum(intptr_t m)
39 {
40         get_max() = m;
41 }
42
43 intptr_t MEM_CacheLimiter_get_maximum()
44 {
45         return get_max();
46 }
47
48 class MEM_CacheLimiterHandleCClass;
49 class MEM_CacheLimiterCClass;
50
51 typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t;
52 typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t;
53 typedef std::list<MEM_CacheLimiterHandleCClass*,
54                   MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t;
55
56 class MEM_CacheLimiterCClass {
57 public:
58         MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_, MEM_CacheLimiter_DataSize_Func data_size)
59                 : data_destructor(data_destructor_), cache(data_size) {
60         }
61         ~MEM_CacheLimiterCClass();
62         
63         handle_t * insert(void * data);
64
65         void destruct(void * data,
66                       list_t::iterator it);
67
68         cache_t * get_cache() {
69                 return &cache;
70         }
71 private:
72         MEM_CacheLimiter_Destruct_Func data_destructor;
73
74         MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
75         
76         list_t cclass_list;
77 };
78
79 class MEM_CacheLimiterHandleCClass {
80 public:
81         MEM_CacheLimiterHandleCClass(void * data_,
82                                    MEM_CacheLimiterCClass * parent_)
83                 : data(data_), parent(parent_) { }
84         ~MEM_CacheLimiterHandleCClass();
85         void set_iter(list_t::iterator it_) {
86                 it = it_;
87         }
88         void set_data(void * data_) {
89                 data = data_;
90         }
91         void * get_data() const {
92                 return data;
93         }
94 private:
95         void * data;
96         MEM_CacheLimiterCClass * parent;
97         list_t::iterator it;
98 };
99
100 handle_t * MEM_CacheLimiterCClass::insert(void * data) 
101 {
102         cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
103         list_t::iterator it = cclass_list.end();
104         --it;
105         cclass_list.back()->set_iter(it);
106         
107         return cache.insert(cclass_list.back());
108 }
109
110 void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it) 
111 {
112         data_destructor(data);
113         cclass_list.erase(it);
114 }
115
116 MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass()
117 {
118         if (data) {
119                 parent->destruct(data, it);
120         }
121 }
122
123 MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
124 {
125         // should not happen, but don't leak memory in this case...
126         for (list_t::iterator it = cclass_list.begin();
127              it != cclass_list.end(); it++) {
128                 (*it)->set_data(0);
129                 delete *it;
130         }
131 }
132
133 // ----------------------------------------------------------------------
134
135 static inline MEM_CacheLimiterCClass* cast(MEM_CacheLimiterC * l)
136 {
137         return (MEM_CacheLimiterCClass*) l;
138 }
139
140 static inline handle_t* cast(MEM_CacheLimiterHandleC * l)
141 {
142         return (handle_t*) l;
143 }
144
145 MEM_CacheLimiterC * new_MEM_CacheLimiter(
146         MEM_CacheLimiter_Destruct_Func data_destructor,
147         MEM_CacheLimiter_DataSize_Func data_size)
148 {
149         return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass(
150                 data_destructor,
151                 data_size);
152 }
153
154 void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This)
155 {
156         delete cast(This);
157 }
158
159 MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert(
160         MEM_CacheLimiterC * This, void * data)
161 {
162         return (MEM_CacheLimiterHandleC *) cast(This)->insert(data);
163 }
164
165 void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This)
166 {
167         cast(This)->get_cache()->enforce_limits();
168 }
169         
170 void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle)
171 {
172         cast(handle)->unmanage();
173 }
174         
175 void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle)
176 {
177         cast(handle)->touch();
178 }
179         
180 void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle)
181 {
182         cast(handle)->ref();
183 }
184         
185 void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle)
186 {
187         cast(handle)->unref();
188 }
189
190 int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle)
191 {
192         return cast(handle)->get_refcount();
193 }
194
195         
196 void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle)
197 {
198         return cast(handle)->get()->get_data();
199 }