Generated on Thu Mar 22 10:39:32 2012 for Gecode by doxygen 1.6.3

node.hpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2006
00008  *
00009  *  Last modified:
00010  *     $Date: 2011-05-02 15:44:28 +0200 (Mon, 02 May 2011) $ by $Author: tack $
00011  *     $Revision: 11981 $
00012  *
00013  *  This file is part of Gecode, the generic constraint
00014  *  development environment:
00015  *     http://www.gecode.org
00016  *
00017  * Permission is hereby granted, free of charge, to any person obtaining
00018  * a copy of this software and associated documentation files (the
00019  * "Software"), to deal in the Software without restriction, including
00020  * without limitation the rights to use, copy, modify, merge, publish,
00021  * distribute, sublicense, and/or sell copies of the Software, and to
00022  * permit persons to whom the Software is furnished to do so, subject to
00023  * the following conditions:
00024  *
00025  * The above copyright notice and this permission notice shall be
00026  * included in all copies or substantial portions of the Software.
00027  *
00028  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00029  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00030  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00031  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00032  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00033  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00034  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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 // STATISTICS: gist-any