Line data Source code
1 : //
2 : // Author: Vladimir Migashko <migashko@gmail.com>, (C) 2012
3 : //
4 : // Copyright: See COPYING file that comes with this distribution
5 : //
6 :
7 : #ifndef VSET_VSET_BUFFER_PERSISTENT_MMAP_AD_TRUNCATE_HPP
8 : #define VSET_VSET_BUFFER_PERSISTENT_MMAP_AD_TRUNCATE_HPP
9 :
10 : #include <vset/buffer/tags.hpp>
11 : #include <vset/buffer/persistent/tags.hpp>
12 : #include <unistd.h>
13 : #include <sys/mman.h>
14 :
15 :
16 : namespace vset { namespace buffer { namespace persistent{ namespace mmap{
17 :
18 9 : struct ad_truncate
19 : {
20 : template<typename T>
21 24 : void operator()( T& t, size_t size)
22 : {
23 : typedef typename T::aspect::template advice_cast<_head_type_>::type head_type;
24 24 : size_t capacity = t.get_aspect().template get<_capacity_>()(t);
25 24 : size_t oldsize = sizeof(head_type) + capacity;
26 24 : size_t newsize = sizeof(head_type) + size;
27 :
28 24 : t.get_aspect().template get<_resize_file_>()(t, newsize);
29 24 : char* olddata = t.get_aspect().template get<_buffer_>();
30 24 : char* data = static_cast<char*>( ::mremap( olddata, oldsize, newsize, MREMAP_MAYMOVE) );
31 24 : if ( data == MAP_FAILED)
32 0 : throw std::runtime_error(strerror(errno));
33 :
34 24 : if ( oldsize < newsize )
35 21 : ::memset( data + oldsize, 0, newsize - oldsize);
36 :
37 24 : t.get_aspect().template get<_buffer_>() = data;
38 24 : t.get_aspect().template get<_buffer_size_>() = newsize;
39 24 : t.get_aspect().template get<_head_>()(t)->set_capacity(size);
40 24 : t.get_aspect().template get<_capacity_value_>() = size;
41 :
42 24 : if ( size <= capacity )
43 : {
44 3 : t.get_aspect().template get<_head_>()(t)->set_size(size);
45 3 : t.get_aspect().template get<_size_value_>() = size;
46 : }
47 24 : t.get_aspect().template get<_sync_>()(t, 0, 0);
48 24 : }
49 : };
50 :
51 : }}}}
52 :
53 : #endif
|