CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bigvector.h
Go to the documentation of this file.
1 
7 #ifndef CVMFS_BIGVECTOR_H_
8 #define CVMFS_BIGVECTOR_H_
9 
10 #include <cassert>
11 #include <cstdlib>
12 
13 #include "util/smalloc.h"
14 
15 template<class Item>
16 class BigVector {
17  public:
20  size_ = 0;
21  shared_buffer_ = false;
22  }
23 
24  explicit BigVector(const size_t num_items) {
25  assert(num_items > 0);
26  buffer_ = Alloc(num_items);
27  size_ = 0;
28  shared_buffer_ = false;
29  }
30 
31  BigVector(const BigVector<Item> &other) { CopyFrom(other); }
32 
34  if (&other == this)
35  return *this;
36 
37  if (!shared_buffer_)
38  Dealloc();
39  CopyFrom(other);
40  return *this;
41  }
42 
44  if (!shared_buffer_)
45  Dealloc();
46  }
47 
48  Item At(const size_t index) const {
49  assert(index < size_);
50  return buffer_[index];
51  }
52 
53  const Item *AtPtr(const size_t index) const {
54  assert(index < size_);
55  return &buffer_[index];
56  }
57 
58  void PushBack(const Item &item) {
59  if (size_ == capacity_)
61  new (buffer_ + size_) Item(item);
62  size_++;
63  }
64 
65  void Replace(size_t index, const Item &item) {
66  assert(index < size_);
67  buffer_[index] = item;
68  }
69 
70  bool IsEmpty() const { return size_ == 0; }
71 
72  void Clear() {
73  Dealloc();
75  }
76 
77  void ShareBuffer(Item **duplicate, bool *large_alloc) {
78  *duplicate = buffer_;
79  *large_alloc = large_alloc_;
80  shared_buffer_ = true;
81  }
82 
83  void DoubleCapacity() {
84  Item *old_buffer = buffer_;
85  bool old_large_alloc = large_alloc_;
86 
87  assert(capacity_ > 0);
88  buffer_ = Alloc(capacity_ * 2);
89  for (size_t i = 0; i < size_; ++i)
90  new (buffer_ + i) Item(old_buffer[i]);
91 
92  FreeBuffer(old_buffer, size_, old_large_alloc);
93  }
94 
97 
98  if (size_ <= kNumInit)
99  return;
100  if (static_cast<float>(size_) >= (0.25 * static_cast<float>(capacity_)))
101  return;
102 
103  bool old_large_alloc = large_alloc_;
104  Item *new_buffer = Alloc(0.5 * static_cast<float>(capacity_));
105  for (size_t i = 0; i < size_; ++i)
106  new (new_buffer + i) Item(buffer_[i]);
107  FreeBuffer(buffer_, size_, old_large_alloc);
108  buffer_ = new_buffer;
109  }
110 
111  // Careful! Only for externally modified buffer.
112  void SetSize(const size_t new_size) {
113  assert(new_size <= capacity_);
114  size_ = new_size;
115  }
116 
117  size_t size() const { return size_; }
118  size_t capacity() const { return capacity_; }
119 
120  private:
121  static const size_t kNumInit = 16;
122  static const size_t kMmapThreshold = 128 * 1024;
123 
124  Item *Alloc(const size_t num_elements) {
125  Item *result;
126  size_t num_bytes = sizeof(Item) * num_elements;
127  if (num_bytes >= kMmapThreshold) {
128  result = static_cast<Item *>(smmap(num_bytes));
129  large_alloc_ = true;
130  } else {
131  result = static_cast<Item *>(smalloc(num_bytes));
132  large_alloc_ = false;
133  }
134  capacity_ = num_elements;
135  return result;
136  }
137 
138  void Dealloc() {
140  buffer_ = NULL;
141  capacity_ = 0;
142  size_ = 0;
143  }
144 
145  void FreeBuffer(Item *buf, const size_t size, const bool large) {
146  for (size_t i = 0; i < size; ++i)
147  buf[i].~Item();
148 
149  if (buf) {
150  if (large) {
151  smunmap(buf);
152  } else {
153  free(buf);
154  }
155  }
156  }
157 
158  void CopyFrom(const BigVector<Item> &other) {
159  buffer_ = Alloc(other.capacity_);
160  for (size_t i = 0; i < other.size_; ++i) {
161  new (buffer_ + i) Item(*other.AtPtr(i));
162  }
163  size_ = other.size_;
164  shared_buffer_ = false;
165  }
166 
167  Item *buffer_;
168  size_t size_;
169  size_t capacity_;
172 };
173 
174 #endif // CVMFS_BIGVECTOR_H_
Item At(const size_t index) const
Definition: bigvector.h:48
void ShareBuffer(Item **duplicate, bool *large_alloc)
Definition: bigvector.h:77
size_t size_
Definition: bigvector.h:168
bool shared_buffer_
Definition: bigvector.h:171
assert((mem||(size==0))&&"Out Of Memory")
~BigVector()
Definition: bigvector.h:43
Item * buffer_
Definition: bigvector.h:167
void Dealloc()
Definition: bigvector.h:138
void FreeBuffer(Item *buf, const size_t size, const bool large)
Definition: bigvector.h:145
void DoubleCapacity()
Definition: bigvector.h:83
BigVector(const BigVector< Item > &other)
Definition: bigvector.h:31
void CopyFrom(const BigVector< Item > &other)
Definition: bigvector.h:158
BigVector< Item > & operator=(const BigVector< Item > &other)
Definition: bigvector.h:33
void SetSize(const size_t new_size)
Definition: bigvector.h:112
void Clear()
Definition: bigvector.h:72
void ShrinkIfOversized()
Definition: bigvector.h:95
size_t capacity() const
Definition: bigvector.h:118
BigVector(const size_t num_items)
Definition: bigvector.h:24
bool IsEmpty() const
Definition: bigvector.h:70
static const size_t kNumInit
Definition: bigvector.h:121
void PushBack(const Item &item)
Definition: bigvector.h:58
BigVector()
Definition: bigvector.h:18
static const size_t kMmapThreshold
Definition: bigvector.h:122
Item * Alloc(const size_t num_elements)
Definition: bigvector.h:124
void Replace(size_t index, const Item &item)
Definition: bigvector.h:65
bool large_alloc_
Definition: bigvector.h:170
size_t capacity_
Definition: bigvector.h:169
const Item * AtPtr(const size_t index) const
Definition: bigvector.h:53
size_t size() const
Definition: bigvector.h:117