node.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 namespace Gecode { namespace Gist {
00039
00040 template<class T>
00041 void
00042 NodeAllocatorBase<T>::allocate(void) {
00043 cur_b++;
00044 cur_t = 0;
00045 if (cur_b==n) {
00046 int oldn = n;
00047 n *= 1.5;
00048 b = heap.realloc<Block*>(b,oldn,n);
00049 }
00050 b[cur_b] = static_cast<Block*>(heap.ralloc(sizeof(Block)));
00051 }
00052
00053 template<class T>
00054 NodeAllocatorBase<T>::NodeAllocatorBase(bool bab) : _bab(bab) {
00055 b = heap.alloc<Block*>(10);
00056 n = 10;
00057 cur_b = -1;
00058 cur_t = NodeBlockSize-1;
00059 }
00060
00061 template<class T>
00062 NodeAllocatorBase<T>::~NodeAllocatorBase(void) {
00063 for (int i=cur_b+1; i--;)
00064 heap.rfree(b[i]);
00065 heap.free<Block*>(b,n);
00066 }
00067
00068 template<class T>
00069 forceinline int
00070 NodeAllocatorBase<T>::allocate(int p) {
00071 cur_t++;
00072 if (cur_t==NodeBlockSize)
00073 allocate();
00074 new (&b[cur_b]->b[cur_t]) T(p);
00075 b[cur_b]->best[cur_t] = -1;
00076 return cur_b*NodeBlockSize+cur_t;
00077 }
00078
00079 template<class T>
00080 forceinline int
00081 NodeAllocatorBase<T>::allocate(Space* root) {
00082 cur_t++;
00083 if (cur_t==NodeBlockSize)
00084 allocate();
00085 new (&b[cur_b]->b[cur_t]) T(root);
00086 b[cur_b]->best[cur_t] = -1;
00087 return cur_b*NodeBlockSize+cur_t;
00088 }
00089
00090 template<class T>
00091 forceinline T*
00092 NodeAllocatorBase<T>::operator [](int i) const {
00093 assert(i/NodeBlockSize < n);
00094 assert(i/NodeBlockSize < cur_b || i%NodeBlockSize <= cur_t);
00095 return &(b[i/NodeBlockSize]->b[i%NodeBlockSize]);
00096 }
00097
00098 template<class T>
00099 forceinline T*
00100 NodeAllocatorBase<T>::best(int i) const {
00101 assert(i/NodeBlockSize < n);
00102 assert(i/NodeBlockSize < cur_b || i%NodeBlockSize <= cur_t);
00103 int bi = b[i/NodeBlockSize]->best[i%NodeBlockSize];
00104 return bi == -1 ? NULL : (*this)[bi];
00105 }
00106
00107 template<class T>
00108 forceinline void
00109 NodeAllocatorBase<T>::setBest(int i, int best) {
00110 assert(i/NodeBlockSize < n);
00111 assert(i/NodeBlockSize < cur_b || i%NodeBlockSize <= cur_t);
00112 b[i/NodeBlockSize]->best[i%NodeBlockSize] = best;
00113 }
00114
00115 template<class T>
00116 forceinline bool
00117 NodeAllocatorBase<T>::bab(void) const {
00118 return _bab;
00119 }
00120
00121 forceinline unsigned int
00122 Node::getTag(void) const {
00123 return static_cast<unsigned int>
00124 (reinterpret_cast<ptrdiff_t>(childrenOrFirstChild) & 3);
00125 }
00126
00127 forceinline void
00128 Node::setTag(unsigned int tag) {
00129 assert(tag <= 3);
00130 assert(getTag() == UNDET);
00131 childrenOrFirstChild = reinterpret_cast<void*>
00132 ( (reinterpret_cast<ptrdiff_t>(childrenOrFirstChild) & ~(3)) | tag);
00133 }
00134
00135 forceinline void*
00136 Node::getPtr(void) const {
00137 return reinterpret_cast<void*>
00138 (reinterpret_cast<ptrdiff_t>(childrenOrFirstChild) & ~(3));
00139 }
00140
00141 forceinline int
00142 Node::getFirstChild(void) const {
00143 return static_cast<int>
00144 ((reinterpret_cast<ptrdiff_t>(childrenOrFirstChild) & ~(3)) >> 2);
00145 }
00146
00147 forceinline
00148 Node::Node(int p, bool failed) : parent(p) {
00149 childrenOrFirstChild = NULL;
00150 noOfChildren = 0;
00151 setTag(failed ? LEAF : UNDET);
00152 }
00153
00154 forceinline int
00155 Node::getParent(void) const {
00156 return parent;
00157 }
00158
00159 forceinline VisualNode*
00160 Node::getParent(const NodeAllocator& na) const {
00161 return parent < 0 ? NULL : na[parent];
00162 }
00163
00164 forceinline bool
00165 Node::isUndetermined(void) const { return getTag() == UNDET; }
00166
00167 forceinline int
00168 Node::getChild(int n) const {
00169 assert(getTag() != UNDET && getTag() != LEAF);
00170 if (getTag() == TWO_CHILDREN) {
00171 assert(n != 1 || noOfChildren <= 0);
00172 return n == 0 ? getFirstChild() : -noOfChildren;
00173 }
00174 assert(n < noOfChildren);
00175 return static_cast<int*>(getPtr())[n];
00176 }
00177
00178 forceinline VisualNode*
00179 Node::getChild(const NodeAllocator& na, int n) const {
00180 return na[getChild(n)];
00181 }
00182
00183 forceinline bool
00184 Node::isRoot(void) const { return parent == -1; }
00185
00186 forceinline unsigned int
00187 Node::getNumberOfChildren(void) const {
00188 switch (getTag()) {
00189 case UNDET: return 0;
00190 case LEAF: return 0;
00191 case TWO_CHILDREN: return 1+(noOfChildren <= 0);
00192 default: return noOfChildren;
00193 }
00194 }
00195
00196 inline int
00197 Node::getIndex(const NodeAllocator& na) const {
00198 if (parent==-1)
00199 return 0;
00200 Node* p = na[parent];
00201 for (int i=p->getNumberOfChildren(); i--;)
00202 if (p->getChild(na,i) == this)
00203 return p->getChild(i);
00204 GECODE_NEVER;
00205 return -1;
00206 }
00207
00208 }}
00209
00210