Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef SMALLSTACK_TYPE_HPP
00013 #define SMALLSTACK_TYPE_HPP
00014
00015 #include "smallvec_type.hpp"
00016 #include "../thread/thread.h"
00017
00023 template<typename Titem, typename Tindex, Tindex Tgrowth_step, Tindex Tmax_size>
00024 class SimplePool {
00025 public:
00026 inline SimplePool() : first_unused(0), first_free(0), mutex(ThreadMutex::New()) {}
00027 inline ~SimplePool() { delete this->mutex; }
00028
00034 inline ThreadMutex *GetMutex() { return this->mutex; }
00035
00040 inline Titem &Get(Tindex index) { return this->data[index]; }
00041
00046 inline Tindex Create()
00047 {
00048 Tindex index = this->FindFirstFree();
00049 if (index < Tmax_size) {
00050 this->data[index].valid = true;
00051 this->first_free = index + 1;
00052 this->first_unused = max(this->first_unused, this->first_free);
00053 }
00054 return index;
00055 }
00056
00061 inline void Destroy(Tindex index)
00062 {
00063 this->data[index].valid = false;
00064 this->first_free = min(this->first_free, index);
00065 }
00066
00067 private:
00068
00069 inline Tindex FindFirstFree()
00070 {
00071 Tindex index = this->first_free;
00072 for (; index < this->first_unused; index++) {
00073 if (!this->data[index].valid) return index;
00074 }
00075
00076 if (index >= this->data.Length() && index < Tmax_size) {
00077 this->data.Resize(index + 1);
00078 }
00079 return index;
00080 }
00081
00082 struct SimplePoolPoolItem : public Titem {
00083 bool valid;
00084 };
00085
00086 Tindex first_unused;
00087 Tindex first_free;
00088
00089 ThreadMutex *mutex;
00090 SmallVector<SimplePoolPoolItem, Tgrowth_step> data;
00091 };
00092
00097 template <typename Titem, typename Tindex>
00098 struct SmallStackItem {
00099 Tindex next;
00100 Titem value;
00101
00107 inline SmallStackItem(const Titem &value, Tindex next) :
00108 next(next), value(value) {}
00109 };
00110
00137 template <typename Titem, typename Tindex, Titem Tinvalid, Tindex Tgrowth_step, Tindex Tmax_size>
00138 class SmallStack : public SmallStackItem<Titem, Tindex> {
00139 public:
00140
00141 typedef SmallStackItem<Titem, Tindex> Item;
00142
00146 struct PooledSmallStack : public Item {
00147 Tindex branch_count;
00148 };
00149
00150 typedef SimplePool<PooledSmallStack, Tindex, Tgrowth_step, Tmax_size> SmallStackPool;
00151
00156 inline SmallStack(const Titem &value = Tinvalid) : Item(value, Tmax_size) {}
00157
00161 inline ~SmallStack()
00162 {
00163
00164 while (this->next != Tmax_size) this->Pop();
00165 }
00166
00171 inline SmallStack(const SmallStack &other) : Item(other) { this->Branch(); }
00172
00178 inline SmallStack &operator=(const SmallStack &other)
00179 {
00180 if (this == &other) return *this;
00181 while (this->next != Tmax_size) this->Pop();
00182 this->next = other.next;
00183 this->value = other.value;
00184
00185
00186 this->Branch();
00187 return *this;
00188 }
00189
00195 inline void Push(const Titem &item)
00196 {
00197 if (this->value != Tinvalid) {
00198 ThreadMutexLocker lock(_pool.GetMutex());
00199 Tindex new_item = _pool.Create();
00200 if (new_item != Tmax_size) {
00201 PooledSmallStack &pushed = _pool.Get(new_item);
00202 pushed.value = this->value;
00203 pushed.next = this->next;
00204 pushed.branch_count = 0;
00205 this->next = new_item;
00206 }
00207 }
00208 this->value = item;
00209 }
00210
00215 inline Titem Pop()
00216 {
00217 Titem ret = this->value;
00218 if (this->next == Tmax_size) {
00219 this->value = Tinvalid;
00220 } else {
00221 ThreadMutexLocker lock(_pool.GetMutex());
00222 PooledSmallStack &popped = _pool.Get(this->next);
00223 this->value = popped.value;
00224 if (popped.branch_count == 0) {
00225 _pool.Destroy(this->next);
00226 } else {
00227 --popped.branch_count;
00228
00229 if (popped.next != Tmax_size) {
00230 ++(_pool.Get(popped.next).branch_count);
00231 }
00232 }
00233
00234
00235
00236
00237 this->next = popped.next;
00238 }
00239 return ret;
00240 }
00241
00246 inline bool IsEmpty() const
00247 {
00248 return this->value == Tinvalid && this->next == Tmax_size;
00249 }
00250
00256 inline bool Contains(const Titem &item) const
00257 {
00258 if (item == Tinvalid || item == this->value) return true;
00259 if (this->next != Tmax_size) {
00260 ThreadMutexLocker lock(_pool.GetMutex());
00261 const SmallStack *in_list = this;
00262 do {
00263 in_list = static_cast<const SmallStack *>(
00264 static_cast<const Item *>(&_pool.Get(in_list->next)));
00265 if (in_list->value == item) return true;
00266 } while (in_list->next != Tmax_size);
00267 }
00268 return false;
00269 }
00270
00271 protected:
00272 static SmallStackPool _pool;
00273
00277 inline void Branch()
00278 {
00279 if (this->next != Tmax_size) {
00280 ThreadMutexLocker lock(_pool.GetMutex());
00281 ++(_pool.Get(this->next).branch_count);
00282 }
00283 }
00284 };
00285
00286 #endif