@@ -20,6 +20,7 @@ class int_vector_mapper
20
20
typedef typename int_vector<t_width>::value_type value_type;
21
21
typedef typename int_vector<t_width>::size_type size_type;
22
22
typedef typename int_vector<t_width>::int_width_type width_type;
23
+ static constexpr uint8_t fixed_int_width = t_width;
23
24
public:
24
25
const size_type append_block_size = 1000000 ;
25
26
private:
@@ -38,31 +39,31 @@ class int_vector_mapper
38
39
~int_vector_mapper ()
39
40
{
40
41
if (m_mapped_data) {
41
- if (t_mode&std::ios_base::out) { // write was possible
42
- if (m_data_offset) {
43
- // update size in the on disk representation and
44
- // truncate if necessary
45
- uint64_t * size_in_file = (uint64_t *)m_mapped_data;
46
- if (*size_in_file != m_wrapper.m_size ) {
47
- *size_in_file = m_wrapper.m_size ;
48
- }
49
- if (t_width==0 ) {
50
- // if size is variable and we map a sdsl vector
51
- // we might have to update the stored width
52
- uint8_t stored_width = m_mapped_data[8 ];
53
- if (stored_width != m_wrapper.m_width ) {
54
- m_mapped_data[8 ] = m_wrapper.m_width ;
55
- }
56
- }
57
- }
58
- }
59
-
60
- auto ret = memory_manager::mem_unmap (m_mapped_data,m_file_size_bytes);
42
+ auto ret = memory_manager::mem_unmap (m_fd,m_mapped_data,m_file_size_bytes);
61
43
if (ret != 0 ) {
62
44
std::cerr << " int_vector_mapper: error unmapping file mapping'"
63
45
<< m_file_name << " ': " << ret << std::endl;
64
46
}
65
47
48
+ if (t_mode&std::ios_base::out) { // write was possible
49
+ if (m_data_offset) { // if the file is not a plain file
50
+ // set std::ios::in to not truncate the file
51
+ osfstream out (m_file_name, std::ios::in);
52
+ if ( out ) {
53
+ out.seekp (0 , std::ios::beg);
54
+ int_vector<t_width>::write_header (m_wrapper.m_size ,
55
+ m_wrapper.m_width ,
56
+ out);
57
+
58
+ // out.seekp(0, std::ios::end);
59
+ } else {
60
+ throw std::runtime_error (" int_vector_mapper: \
61
+ could not open file for header update" );
62
+ }
63
+ }
64
+ }
65
+
66
+
66
67
if (t_mode&std::ios_base::out) {
67
68
// do we have to truncate?
68
69
size_type current_bit_size = m_wrapper.m_size ;
@@ -95,6 +96,7 @@ class int_vector_mapper
95
96
m_wrapper.m_data = nullptr ;
96
97
m_wrapper.m_size = 0 ;
97
98
}
99
+
98
100
int_vector_mapper (int_vector_mapper&& ivm)
99
101
{
100
102
m_wrapper.m_data = ivm.m_wrapper .m_data ;
@@ -107,6 +109,7 @@ class int_vector_mapper
107
109
ivm.m_mapped_data = nullptr ;
108
110
ivm.m_fd = -1 ;
109
111
}
112
+
110
113
int_vector_mapper& operator =(int_vector_mapper&& ivm)
111
114
{
112
115
m_wrapper.m_data = ivm.m_wrapper .m_data ;
@@ -120,32 +123,35 @@ class int_vector_mapper
120
123
ivm.m_fd = -1 ;
121
124
return (*this );
122
125
}
126
+
123
127
int_vector_mapper (const std::string& key,const cache_config& config)
124
128
: int_vector_mapper(cache_file_name(key, config)) {}
125
129
126
130
127
131
int_vector_mapper (const std::string filename,
128
132
bool is_plain = false ,
129
133
bool delete_on_close = false ) :
134
+ m_data_offset (0 ),
130
135
m_file_name (filename), m_delete_on_close(delete_on_close)
131
136
{
132
137
size_type size_in_bits = 0 ;
133
138
uint8_t int_width = t_width;
134
139
{
135
- std::ifstream f (filename,std::ifstream::binary);
140
+ isfstream f (filename,std::ifstream::binary);
136
141
if (!f.is_open ()) {
137
142
throw std::runtime_error (
138
- " int_vector_mapper: file does not exist." );
143
+ " int_vector_mapper: file " +
144
+ m_file_name +
145
+ " does not exist." );
139
146
}
140
147
if (!is_plain) {
141
- int_vector<t_width>::read_header (size_in_bits, int_width, f);
148
+ m_data_offset = int_vector<t_width>::read_header (size_in_bits, int_width, f);
142
149
}
143
150
}
151
+
144
152
m_file_size_bytes = util::file_size (m_file_name);
145
153
146
- if (!is_plain) {
147
- m_data_offset = 8 ;
148
- } else {
154
+ if (is_plain) {
149
155
if (8 != t_width and 16 != t_width and 32 != t_width and 64 != t_width) {
150
156
throw std::runtime_error (" int_vector_mapper: plain vector can "
151
157
" only be of width 8, 16, 32, 64." );
@@ -158,7 +164,6 @@ class int_vector_mapper
158
164
}
159
165
}
160
166
size_in_bits = m_file_size_bytes * 8 ;
161
- m_data_offset = 0 ;
162
167
}
163
168
164
169
// open backend file depending on mode
@@ -170,6 +175,7 @@ class int_vector_mapper
170
175
throw std::runtime_error (open_error);
171
176
}
172
177
178
+
173
179
// prepare for mmap
174
180
m_wrapper.width (int_width);
175
181
// mmap data
@@ -203,7 +209,7 @@ class int_vector_mapper
203
209
size_type new_size_in_bytes = ((bit_size + 63 ) >> 6 ) << 3 ;
204
210
if (m_file_size_bytes != new_size_in_bytes + m_data_offset) {
205
211
if (m_mapped_data) {
206
- auto ret = memory_manager::mem_unmap (m_mapped_data,m_file_size_bytes);
212
+ auto ret = memory_manager::mem_unmap (m_fd, m_mapped_data,m_file_size_bytes);
207
213
if (ret != 0 ) {
208
214
std::cerr << " int_vector_mapper: error unmapping file mapping'"
209
215
<< m_file_name << " ': " << ret << std::endl;
@@ -349,7 +355,7 @@ class temp_file_buffer
349
355
throw std::runtime_error (" could not create temporary file." );
350
356
}
351
357
#else
352
- sprintf (tmp_file_name, " %s/tmp_mapper_file_%lu_XXXXXX .sdsl" ,dir.c_str (),util::pid ());
358
+ sprintf (tmp_file_name, " %s/tmp_mapper_file_%llu_XXXXXX .sdsl" ,dir.c_str (),util::pid ());
353
359
int fd = mkstemps (tmp_file_name,5 );
354
360
if (fd == -1 ) {
355
361
throw std::runtime_error (" could not create temporary file." );
@@ -386,7 +392,7 @@ class temp_file_buffer
386
392
387
393
// creates emtpy int_vector<> that will not be deleted
388
394
template <uint8_t t_width = 0 >
389
- class write_out_buffer
395
+ class write_out_mapper
390
396
{
391
397
public:
392
398
static int_vector_mapper<t_width> create (const std::string& key,cache_config& config)
@@ -403,6 +409,15 @@ class write_out_buffer
403
409
store_to_file (tmp_vector,file_name);
404
410
return int_vector_mapper<t_width,std::ios_base::out|std::ios_base::in>(file_name,false ,false );
405
411
}
412
+ static int_vector_mapper<t_width> create (const std::string& file_name,size_t size, uint8_t int_width = t_width)
413
+ {
414
+ // write empty int_vector to init the file
415
+ int_vector<t_width> tmp_vector (0 ,0 ,int_width);
416
+ store_to_file (tmp_vector,file_name);
417
+ int_vector_mapper<t_width,std::ios_base::out|std::ios_base::in> mapper (file_name,false ,false );
418
+ mapper.resize (size);
419
+ return mapper;
420
+ }
406
421
};
407
422
408
423
template <std::ios_base::openmode t_mode = std::ios_base::out|std::ios_base::in>
0 commit comments