forked from johannesthoma/mmap_allocator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmmappable_vector.h
139 lines (119 loc) · 3.03 KB
/
mmappable_vector.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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef _MMAPPABLE_VECTOR_H
#define _MMAPPABLE_VECTOR_H
#include <memory>
#include <string>
#include <stdio.h>
#include <vector>
#include "mmap_allocator.h"
namespace mmap_allocator_namespace {
template <typename T, typename A = mmap_allocator<T> >
class mmappable_vector: public std::vector<T, A> {
public:
typedef std::vector<T, A> Base;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::iterator iterator;
typedef T value_type;
typedef A allocator_type;
mmappable_vector():
Base()
{
}
mmappable_vector(const mmappable_vector<T, A> &other):
Base(other)
{
}
explicit mmappable_vector(size_t n):
Base()
{
mmap_file(n);
}
explicit mmappable_vector(A alloc):
Base(alloc)
{
}
mmappable_vector(iterator from, iterator to):
Base(from, to)
{
}
template <typename Iter>
mmappable_vector(Iter first, Iter last, A a = A()):
Base(first, last, a)
{
}
mmappable_vector(int n, T val, A alloc):
Base(n, val, alloc)
{
}
mmappable_vector(int n, T val):
Base(n, val)
{
}
mmappable_vector(std::vector<T,std::allocator<T> > v):
std::vector<T,std::allocator<T> >(v)
{
}
/* Use this only when the allocator is already initialized. */
void mmap_file(size_t n)
{
Base::reserve(n);
_M_set_finish(n);
}
void mmap_file(std::string filename, enum access_mode access_mode, const off_t offset, const size_t n, int flags = 0)
{
if (Base::size() > 0) {
throw mmap_allocator_exception("Remapping currently not implemented.");
}
#ifdef __GNUC__
#if __GNUC__ == 4
A *the_allocator = &Base::_M_get_Tp_allocator();
#elif __GNUC__ == 3
A *the_allocator = static_cast<A*>(&(this->Base::_M_impl));
#else
#error "GNU C++ not version 3 or 4, please implement me"
#endif
#else
#error "Not GNU C++, please either implement me or use GCC"
#endif
the_allocator->filename = filename;
the_allocator->offset = offset;
the_allocator->access_mode = access_mode;
the_allocator->map_whole_file = (flags & MAP_WHOLE_FILE) != 0;
the_allocator->allow_remap = (flags & ALLOW_REMAP) != 0;
the_allocator->bypass_file_pool = (flags & BYPASS_FILE_POOL) != 0;
the_allocator->keep_forever = (flags & KEEP_FOREVER) != 0;
mmap_file(n);
}
void munmap_file(void)
{
size_t n = Base::size();
#ifdef __GNUC__
Base::_M_deallocate(Base::_M_impl._M_start, n);
Base::_M_impl._M_start = 0;
Base::_M_impl._M_finish = 0;
Base::_M_impl._M_end_of_storage = 0;
#else
#error "Not GNU C++, please either implement me or use GCC"
#endif
}
private:
void _M_set_finish(size_t n)
{
#ifdef __GNUC__
Base::_M_impl._M_finish = Base::_M_impl._M_start + n;
#else
#error "Not GNU C++, please either implement me or use GCC"
#endif
}
};
template <typename T>
std::vector<T> to_std_vector(const mmappable_vector<T> &v)
{
return std::vector<T>(v.begin(), v.end());
}
template <typename T>
mmappable_vector<T> to_mmappable_vector(const std::vector<T> &v)
{
return mmappable_vector<T>(v.begin(), v.end());
}
}
#endif /* MMAPPABLE_VECTOR_H */