libUTL++
SpanAllocator.h
1 #pragma once
2 
4 
5 #include <libutl/SpanCol.h>
6 
8 
9 UTL_NS_BEGIN;
10 
12 
22 
24 template <class T, class D = T>
25 class SpanAllocator : public SpanCol<T, D>
26 {
28 
29 public:
30  typedef typename SpanCol<T, D>::iterator iterator;
31 
32 public:
33  virtual void copy(const Object& object);
34 
35  virtual void dump(Stream& os, uint_t level = uint_t_max) const;
36 
37  virtual void serialize(Stream& stream, uint_t io, uint_t mode = ser_default);
38 
44  Span<T, D> alloc(D size);
45 
47  void clear();
48 
50  void
51  free(const Span<T, D>& span)
52  {
53  if (this->isOwner())
54  free(span.clone());
55  else
56  free(&span);
57  }
58 
60  void
61  free(const Span<T, D>* span)
62  {
63  this->add(span);
64  }
65 
66  virtual bool
67  remove(const Object& key)
68  {
69  return super::remove(key) && _spans.remove(key.getKey());
70  }
71 
73  void
74  remove(const Span<T, D>& span)
75  {
76  super::remove(span);
77  }
78 
79 protected:
80  virtual void onAdd(const Object& object);
81  virtual void onRemove(const Object& object);
82  virtual Span<T, D> remove(Object& object, const Span<T, D>& span);
83 
84 private:
85  void init();
86  void
87  deInit()
88  {
89  }
90 
91 private:
92  RBtree _spans;
93 };
94 
96 
97 template <class T, class D>
98 void
100 {
101  super::clear();
102  _spans.clear();
103 }
104 
106 
107 template <class T, class D>
108 void
110 {
111  auto& sa = utl::cast<SpanAllocator<T, D>>(object);
112  super::copy(sa);
113  _spans.clear();
114  for (auto span : *this)
115  {
116  _spans.add(span);
117  }
118 }
119 
121 
122 template <class T, class D>
123 void
125 {
126  super::dump(os, level);
127 }
128 
130 
131 template <class T, class D>
132 void
134 {
135  super::serializeFast(Span<T, D>::getThisClass(), stream, io, mode);
136  if (io == io_rd)
137  {
138  for (auto span : *this)
139  {
140  _spans.add(span);
141  }
142  }
143 }
144 
146 
147 template <class T, class D>
150 {
151  Span<T, D> res;
152 
153  // find the smallest free span that is large enough
154  const BinTreeNode* node = _spans.root().node();
155  D bestSize;
156  bool found = false;
157  while (!node->isLeaf())
158  {
159  auto& nodeKey = node->get()->getKey();
160  if (!nodeKey.isA2(Span, T, D))
161  {
162  node = node->left();
163  continue;
164  }
165  const Span<T, D>& span = (const Span<T, D>&)nodeKey;
166  if (span.size() < size)
167  {
168  node = node->right();
169  }
170  else
171  {
172  if (!found || (span.size() < bestSize))
173  {
174  res.setBegin(span.begin());
175  res.setEnd(span.begin() + size);
176  bestSize = span.size();
177  found = true;
178  }
179  node = node->left();
180  }
181  }
182 
183  // remove the span if the allocation is successful
184  if (found)
185  {
186  res.setRelaxed(true);
187  remove(res);
188  res.setRelaxed(false);
189  }
190 
191  return res;
192 }
193 
195 
196 template <class T, class D>
197 void
198 SpanAllocator<T, D>::onAdd(const Object& object)
199 {
200  _spans.add(object.getKey());
201 }
202 
204 
205 template <class T, class D>
206 void
208 {
209  _spans.remove(object.getKey());
210 }
211 
213 
214 template <class T, class D>
216 SpanAllocator<T, D>::remove(Object& object, const Span<T, D>& span)
217 {
218  const Span<T, D>& objSpan = (const Span<T, D>&)object.getKey();
219  _spans.remove(objSpan);
220  Span<T, D> rhsSpan = super::remove(object, span);
221  if (!objSpan.isNil())
222  {
223  _spans.add(objSpan);
224  }
225  return rhsSpan;
226 }
227 
229 
230 template <class T, class D>
231 void
233 {
234  _spans.setOwner(false);
235  _spans.setOrdering(new SpanSizeOrdering<T, D>(), sort_none);
236 }
237 
239 
240 UTL_NS_END;
241 
243 
virtual bool remove(const Object &key)
Remove the object matching the given key.
Definition: SpanAllocator.h:67
const T & begin() const
Get the beginning of the span.
Definition: Span.h:72
void serialize(bool &b, Stream &stream, uint_t io, uint_t mode=ser_default)
Serialize a boolean.
void deInit()
De-initialize UTL++.
#define UTL_CLASS_DECL_TPL2_TPL2(DC, DC_T1, DC_T2, BC, BC_T1, BC_T2)
Declaration of standard UTL++ functionality for a template class with two parameters, where the base class also has two template parameters.
Definition: macros.h:739
void setEnd(const T &end)
Set the end of the span.
Definition: Span.h:93
D size() const
Return the size (end - begin).
Definition: Span.h:136
default representation (via getSerializeMode())
Definition: util.h:75
void remove(FwdIt &begin, const FwdIt &end, bool cmp=false, const Predicate *pred=nullptr, bool predVal=false)
Remove objects from a sequence.
Order spans by size.
Definition: Span.h:261
Red/black tree.
Definition: RBtree.h:37
void copy(T *dest, const T *src, size_t len)
Copy one array of objects to another.
Definition: util_inl.h:690
void free(const Span< T, D > *span)
Free the given span.
Definition: SpanAllocator.h:61
read
Definition: util.h:58
BinTreeNode * right() const
Return the right child.
Definition: BinTreeNode.h:130
Span collection.
Definition: SpanCol.h:55
bool isLeaf() const
Determine whether self is a leaf node.
Definition: BinTreeNode.h:65
In-order bi-directional BinTree iterator.
Definition: BinTreeIt.h:22
do not sort
Definition: algorithms.h:26
Binary tree node.
Definition: BinTreeNode.h:31
void setRelaxed(bool relaxed)
Set the relaxed flag.
Definition: Span.h:129
unsigned int uint_t
Unsigned integer.
Definition: types.h:59
void setBegin(const T &begin)
Set the beginning of the span.
Definition: Span.h:79
#define UTL_CLASS_IMPL_TPL2(className, T1, T2)
Implementation of standard UTL++ functionality for a template class with two parameters.
Definition: macros.h:917
const uint_t uint_t_max
Maximum uint_t value.
Stream I/O abstraction.
Definition: Stream.h:68
virtual const Object & getKey() const
Get the key for this object.
Span allocator.
Definition: SpanAllocator.h:25
void free(const Span< T, D > &span)
Free the given span.
Definition: SpanAllocator.h:51
Object * get() const
Get the contained object.
Definition: BinTreeNode.h:58
bool isNil() const
Determine whether the span is nil.
Definition: Span.h:108
Span of values.
Definition: Span.h:47
BinTreeNode * left() const
Return the left child.
Definition: BinTreeNode.h:93
Root of UTL++ class hierarchy.
Definition: Object.h:52
Span< T, D > remove(const Span< T, D > &span)
Remove the given span from self.
Definition: Span.h:420
void dump(const FwdIt &begin, const FwdIt &end, Stream &os, uint_t level=uint_t_max, bool key=false, bool printClassName=false, uint_t indent=0, const char *separator=nullptr)
Dump objects to the given stream (with Object::dump()).
void init()
Initialize UTL++.