-
Notifications
You must be signed in to change notification settings - Fork 1
/
cachingheap.h
104 lines (78 loc) · 2.09 KB
/
cachingheap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// -*- C++ -*-
#ifndef _CACHINGHEAP_H_
#define _CACHINGHEAP_H_
#include "vamcommon.h"
namespace VAM {
// CachingHeap: a heap that caches objects of a fixed size allocated from SuperHeap
template <class SuperHeap>
class CachingHeap : public SuperHeap {
public:
CachingHeap()
: _cached_objects(NULL),
_num_cached(0),
_target_cache_size(1) {
}
inline void * malloc(size_t size) {
void * ptr;
// allocate from the cache
if (_num_cached > 0) {
assert(_cached_objects != NULL);
ptr = _cached_objects;
_cached_objects = _cached_objects->next;
_num_cached--;
}
// refill the cache
else {
assert(_cached_objects == NULL);
ptr = SuperHeap::malloc(size);
if (ptr == NULL)
return NULL;
if (_target_cache_size < MAX_CACHE_SIZE)
_target_cache_size <<= 1;
CachedObject * last_allocated = reinterpret_cast<CachedObject *>(SuperHeap::malloc(size));
_cached_objects = last_allocated;
while (last_allocated != NULL && _num_cached++ < _target_cache_size) {
CachedObject * this_allocated = reinterpret_cast<CachedObject *>(SuperHeap::malloc(size));
last_allocated->next = this_allocated;
last_allocated = this_allocated;
}
if (last_allocated != NULL)
last_allocated->next = NULL;
}
return ptr;
}
inline void free(void * ptr) {
// free to the cache
if (_num_cached < MAX_CACHE_SIZE) {
CachedObject * this_freed = reinterpret_cast<CachedObject *>(ptr);
this_freed->next = _cached_objects;
_cached_objects = this_freed;
_num_cached++;
}
// clean the cache
else {
SuperHeap::free(ptr);
if (_target_cache_size > 1)
_target_cache_size >>= 1;
while (_num_cached > _target_cache_size) {
CachedObject * free_one = _cached_objects;
assert(free_one != NULL);
_cached_objects = _cached_objects->next;
_num_cached--;
SuperHeap::free(free_one);
}
}
}
private:
enum {
MAX_CACHE_SIZE = 32,
};
struct CachedObject {
CachedObject * next;
};
CachedObject * _cached_objects;
size_t _num_cached;
size_t _target_cache_size;
}; // end of class CachingHeap
}; // end of namespace VAM
#endif