forked from kohler/masstree-beta
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hashallocator.hh
117 lines (96 loc) · 2.7 KB
/
hashallocator.hh
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
105
106
107
108
109
110
111
112
113
114
115
116
117
/* Masstree
* Eddie Kohler, Yandong Mao, Robert Morris
* Copyright (c) 2012-2013 President and Fellows of Harvard College
* Copyright (c) 2012-2013 Massachusetts Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, subject to the conditions
* listed in the Masstree LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the Masstree LICENSE file; the license in that file
* is legally binding.
*/
#ifndef CLICK_HASHALLOCATOR_HH
#define CLICK_HASHALLOCATOR_HH
#include <stddef.h>
#include <assert.h>
#if HAVE_VALGRIND && HAVE_VALGRIND_MEMCHECK_H
# include <valgrind/memcheck.h>
#endif
class HashAllocator { public:
HashAllocator(size_t size);
~HashAllocator();
inline void increase_size(size_t new_size) {
assert(!_free && !_buffer && new_size >= _size);
_size = new_size;
}
inline void *allocate();
inline void deallocate(void *p);
void swap(HashAllocator &x);
private:
struct link {
link *next;
};
struct buffer {
buffer *next;
size_t pos;
size_t maxpos;
};
enum {
min_buffer_size = 1024,
#if CLICK_LINUXMODULE
max_buffer_size = 16384,
#else
max_buffer_size = 1048576,
#endif
min_nelements = 8
};
link *_free;
buffer *_buffer;
size_t _size;
void *hard_allocate();
HashAllocator(const HashAllocator &x);
HashAllocator &operator=(const HashAllocator &x);
};
template <size_t size>
class SizedHashAllocator : public HashAllocator { public:
SizedHashAllocator()
: HashAllocator(size) {
}
};
inline void *HashAllocator::allocate()
{
if (link *l = _free) {
#ifdef VALGRIND_MEMPOOL_ALLOC
VALGRIND_MEMPOOL_ALLOC(this, l, _size);
VALGRIND_MAKE_MEM_DEFINED(&l->next, sizeof(l->next));
#endif
_free = l->next;
#ifdef VALGRIND_MAKE_MEM_DEFINED
VALGRIND_MAKE_MEM_UNDEFINED(&l->next, sizeof(l->next));
#endif
return l;
} else if (_buffer && _buffer->pos < _buffer->maxpos) {
void *data = reinterpret_cast<char *>(_buffer) + _buffer->pos;
_buffer->pos += _size;
#ifdef VALGRIND_MEMPOOL_ALLOC
VALGRIND_MEMPOOL_ALLOC(this, data, _size);
#endif
return data;
} else
return hard_allocate();
}
inline void HashAllocator::deallocate(void *p)
{
if (p) {
reinterpret_cast<link *>(p)->next = _free;
_free = reinterpret_cast<link *>(p);
#ifdef VALGRIND_MEMPOOL_FREE
VALGRIND_MEMPOOL_FREE(this, p);
#endif
}
}
#endif