PMDK C++ bindings  1.9.1
This is the C++ bindings documentation for PMDK's libpmemobj.
segment_vector_policies.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2019, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
38 #ifndef LIBPMEMOBJ_SEGMENT_VECTOR_POLICIES_HPP
39 #define LIBPMEMOBJ_SEGMENT_VECTOR_POLICIES_HPP
40 
44 #include <vector>
45 
46 namespace pmem
47 {
48 namespace obj
49 {
50 namespace segment_vector_internal
51 {
52 template <typename T>
53 using array_64 = array<T, 64>;
54 
55 template <typename Container>
56 using resize_method =
57  decltype(std::declval<Container>().resize(std::declval<size_t>()));
58 
59 template <typename Container>
60 using container_has_resize = detail::supports<Container, resize_method>;
61 
62 template <typename Container, bool = container_has_resize<Container>::value>
63 struct segment_vector_resize {
64  using segment_vector_type = Container;
65 
66  static void
67  resize(segment_vector_type &c, size_t n)
68  {
69  c.resize(n);
70  }
71 };
72 
73 template <typename Container>
74 struct segment_vector_resize<Container, false> {
75  using segment_vector_type = Container;
76 
77  static void
78  resize(segment_vector_type &c, size_t n)
79  {
80  }
81 };
82 
83 template <template <typename> class SegmentVectorType,
84  template <typename> class SegmentType, size_t SegmentSize>
85 class fixed_size_policy {
86 public:
87  /* Traits */
88  template <typename T>
89  using segment_vector_type = SegmentVectorType<SegmentType<T>>;
90 
91  template <typename T>
92  using segment_type = SegmentType<T>;
93 
94  template <typename T>
95  using value_type = typename segment_type<T>::value_type;
96 
97  using size_type = std::size_t;
98 
99  template <typename T>
100  using segment_vector_resize_type =
101  segment_vector_resize<segment_vector_type<T>>;
102 
103  static constexpr size_type Size = SegmentSize;
104 
105  template <typename T>
106  static void
107  resize(segment_vector_type<T> &c, size_type n)
108  {
109  segment_vector_resize_type<T>::resize(c, n);
110  }
111 
117  static size_type
118  get_segment(size_type index)
119  {
120  return index / Size;
121  }
127  static size_type
128  segment_top(size_type segment_index)
129  {
130  return segment_index * Size;
131  }
137  static size_type
138  segment_size(size_type segment_index)
139  {
140  return Size;
141  }
147  static size_type
148  index_in_segment(size_type index)
149  {
150  return index % Size;
151  }
152 
156  template <typename T>
157  static size_type
158  max_size(const segment_vector_type<T> &seg_storage)
159  {
160  return seg_storage.max_size() * SegmentSize;
161  }
162 
166  static size_type
167  capacity(size_type segment_index)
168  {
169  return (segment_index + 1) * Size;
170  }
171 };
172 
173 template <template <typename> class SegmentVectorType,
174  template <typename> class SegmentType>
175 class exponential_size_policy {
176 public:
177  /* Traits */
178  template <typename T>
179  using segment_vector_type = SegmentVectorType<SegmentType<T>>;
180 
181  template <typename T>
182  using segment_type = SegmentType<T>;
183 
184  template <typename T>
185  using value_type = typename segment_type<T>::value_type;
186 
187  using size_type = std::size_t;
188 
189  template <typename T>
190  using segment_vector_resize_type =
191  segment_vector_resize<segment_vector_type<T>>;
192 
193  template <typename T>
194  static void
195  resize(segment_vector_type<T> &c, size_type n)
196  {
197  segment_vector_resize_type<T>::resize(c, n);
198  }
199 
205  static size_type
206  get_segment(size_type index)
207  {
208  return static_cast<size_type>(detail::Log2(index | 1));
209  }
215  static size_type
216  segment_top(size_type segment_index)
217  {
218  return (size_type(1) << segment_index) & ~size_type(1);
219  }
225  static size_type
226  segment_size(size_type segment_index)
227  {
228  return (segment_index == 0) ? 2 : segment_top(segment_index);
229  }
235  static size_type
236  index_in_segment(size_type index)
237  {
238  return index - segment_top(get_segment(index));
239  }
240 
244  template <typename T>
245  static size_t
246  max_size(const segment_vector_type<T> &)
247  {
248  return segment_size(get_segment(PMEMOBJ_MAX_ALLOC_SIZE /
249  sizeof(value_type<T>)) +
250  1);
251  }
252 
256  static size_type
257  capacity(size_type segment_index)
258  {
259  if (segment_index == 0)
260  return 2;
261  return segment_size(segment_index) * 2;
262  }
263 };
264 
265 } /* segment_vector_internal namespace */
266 } /* namespace obj */
267 } /* namespace pmem */
268 
269 #endif /* LIBPMEMOBJ_SEGMENT_VECTOR_POLICIES_HPP */
vector.hpp
Vector container with std::vector compatible interface.
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:44
template_helpers.hpp
Commonly used SFINAE helpers.
array.hpp
Array container with std::array compatible interface.