00001
00029 #ifndef ABA_ACTIVE_INC
00030 #define ABA_ACTIVE_INC
00031
00032 #include "abacus/master.h"
00033 #include "abacus/active.h"
00034 #include "abacus/poolslotref.h"
00035 #include "abacus/sparvec.h"
00036 #include "abacus/convar.h"
00037 #include "abacus/poolslot.h"
00038
00039 #ifdef ABACUS_PARALLEL
00040 #include "abacus/message.h"
00041 #include "abacus/constraint.h"
00042 #include "abacus/variable.h"
00043 #include "abacus/debug.h"
00044 #endif
00045
00046 template<class BaseType, class CoType>
00047 ABA_ACTIVE<BaseType, CoType>::ABA_ACTIVE(ABA_MASTER *master, int max)
00048 :
00049 master_(master),
00050 n_(0),
00051 active_(master, max),
00052 redundantAge_(master, max, 0)
00053 { }
00054
00055 template <class BaseType, class CoType>
00056 ABA_ACTIVE<BaseType, CoType>::ABA_ACTIVE(ABA_MASTER *master,
00057 ABA_ACTIVE<BaseType, CoType> *a,
00058 int max)
00059 :
00060 master_(master),
00061 n_(0),
00062 active_(master, max),
00063 redundantAge_(master, max, 0)
00064 {
00065 n_ = max < a->number() ? max : a->number();
00066
00067 for (int i = 0; i < n_; i++)
00068 active_[i] = new ABA_POOLSLOTREF<BaseType, CoType>(*(a->active_[i]));
00069 }
00070
00071 template <class BaseType, class CoType>
00072 ABA_ACTIVE<BaseType, CoType>::ABA_ACTIVE(const ABA_ACTIVE<BaseType, CoType> &rhs)
00073 :
00074 master_(rhs.master_),
00075 n_(rhs.n_),
00076 active_(rhs.master_, rhs.max()),
00077 redundantAge_(master_, rhs.max(), 0)
00078 {
00079 for (int i = 0; i < n_; i++) {
00080 active_[i] = new ABA_POOLSLOTREF<BaseType, CoType>(*(rhs.active_[i]));
00081 redundantAge_[i] = rhs.redundantAge_[i];
00082 }
00083 }
00084
00085 template <class BaseType, class CoType>
00086 ABA_ACTIVE<BaseType, CoType>::~ABA_ACTIVE()
00087 {
00088 for (int i = 0; i < n_; i++)
00089 delete active_[i];
00090 }
00091
00092 #ifdef ABACUS_PARALLEL
00093
00094 template<class BaseType, class CoType>
00095 ABA_ACTIVE<BaseType, CoType>::ABA_ACTIVE(const ABA_MASTER *master, ABA_MESSAGE &msg,
00096 ABA_BUFFER<ABA_ID> **idBuffer, ABA_BUFFER<int> **needed)
00097 :
00098 master_(master),
00099 n_(msg.unpackInt()),
00100 active_(master, msg.unpackInt()),
00101 redundantAge_(master, msg)
00102 {
00103 *idBuffer = new ABA_BUFFER<ABA_ID>(master, n_);
00104 *needed = new ABA_BUFFER<int>(master, n_);
00105
00106 for (int i = 0; i < n_; i++) {
00107 ABA_ID id(msg);
00108 (*idBuffer)->push(id);
00109 if (id.isInitialized()) {
00110 ABA_POOL<BaseType, CoType> *pool = (ABA_POOL<BaseType, CoType>*)
00111 master_->parmaster()->getPool(id.index());
00112 ABA_POOLSLOT<BaseType, CoType> *ps = pool->findSlot(id);
00113 if (ps)
00114 active_[i] = new ABA_POOLSLOTREF<BaseType, CoType>(ps);
00115 else {
00116 (*needed)->push(i);
00117 active_[i] = 0;
00118 }
00119 }
00120 else
00121 active_[i] = 0;
00122 }
00123 }
00124
00125 template<class BaseType, class CoType>
00126 void ABA_ACTIVE<BaseType, CoType>::unpackNeeded(ABA_MESSAGE &msg,
00127 const ABA_BUFFER<ABA_ID> &idBuffer,
00128 const ABA_BUFFER<int> &needed)
00129 {
00130 for (int i = 0; i < needed.number(); i++) {
00131 int classId;
00132 msg.unpack(classId);
00133 BaseType *cv = (BaseType*) master_->unpackConVar(msg, classId);
00134 const ABA_ID &id = idBuffer[needed[i]];
00135 if (debug(DEBUG_MESSAGE_CONVAR)) {
00136 master_->out() << "DEBUG_MESSAGE_CONVAR: Constraint/Variable " << id
00137 << " (classId=" << classId << ") received." << endl;
00138 }
00139 ABA_POOL<BaseType, CoType> *pool = (ABA_POOL<BaseType, CoType>*)
00140 master_->parmaster()->getPool(id.index());
00141 ABA_POOLSLOT<BaseType, CoType> *ps = pool->insert(cv);
00142 if (ps == 0) {
00143 master_->err() << "ABA_ACTIVE::ABA_ACTIVE(): no room to insert constraint"
00144 " into pool." << endl;
00145 exit(Fatal);
00146 }
00147 ps->setIdentification(id);
00148 active_[needed[i]] = new ABA_POOLSLOTREF<BaseType, CoType>(ps);
00149 }
00150 }
00151
00152 template<class BaseType, class CoType>
00153 void ABA_ACTIVE<BaseType, CoType>::pack(ABA_MESSAGE &msg) const
00154 {
00155 msg.pack(n_);
00156 msg.pack(active_.size());
00157 redundantAge_.pack(msg, n_);
00158
00159 ABA_ID uninitializedId;
00160 for (int i = 0; i < n_; i++) {
00161 if (active_[i]->conVar() == 0)
00162 uninitializedId.pack(msg);
00163 else {
00164 ABA_POOLSLOT<BaseType, CoType> *ps = active_[i]->slot();
00165 if (!ps->getIdentification().isInitialized())
00166 ps->setNewIdentification();
00167 ps->getIdentification().pack(msg);
00168 }
00169 }
00170 }
00171
00172 template<class BaseType, class CoType>
00173 void ABA_ACTIVE<BaseType, CoType>::packNeeded(ABA_MESSAGE &msg,
00174 const ABA_BUFFER<int> &needed) const
00175 {
00176 for (int i = 0; i< needed.number(); i++) {
00177 BaseType *cv = active_[needed[i]]->conVar();
00178 if (debug(DEBUG_MESSAGE_CONVAR)) {
00179 master_->out() << "DEBUG_MESSAGE_CONVAR: sending Constraint/Variable "
00180 << active_[needed[i]]->slot()->getIdentification()
00181 << " (classId=" << cv->classId() << ")..." << endl;
00182 }
00183 msg.pack(cv->classId());
00184 cv->pack(msg);
00185 }
00186 }
00187
00188 #endif
00189
00190 template <class BaseType, class CoType>
00191 ostream &operator<<(ostream &out, const ABA_ACTIVE<BaseType, CoType> &rhs)
00192 {
00193 BaseType *cv;
00194 for (int i = 0; i < rhs.n_; i++) {
00195 out << i << ": ";
00196 if (cv = rhs.active_[i]->conVar())
00197 cv->print(out);
00198 else
00199 out << "void" << endl;
00200 }
00201 return out;
00202 }
00203
00204 template <class BaseType, class CoType>
00205 inline int ABA_ACTIVE<BaseType, CoType>::number() const
00206 {
00207 return n_;
00208 }
00209
00210 template <class BaseType, class CoType>
00211 inline int ABA_ACTIVE<BaseType, CoType>::max() const
00212 {
00213 return active_.size();
00214 }
00215
00216 template <class BaseType, class CoType>
00217 BaseType* ABA_ACTIVE<BaseType, CoType>::operator[](int i)
00218 {
00219 #ifdef ABACUSSAFE
00220 if (i > n_) {
00221 master_->err() << "ABA_ACTIVE::operator[] : no active item in slot " << i << "." << endl;
00222 exit(Fatal);
00223 }
00224 #endif
00225
00226 if (active_[i]) return active_[i]->conVar();
00227 else return 0;
00228 }
00229
00230 template <class BaseType, class CoType>
00231 inline ABA_POOLSLOTREF<BaseType, CoType> * ABA_ACTIVE<BaseType, CoType>::poolSlotRef(int i)
00232 {
00233 return active_[i];
00234 }
00235
00236 template <class BaseType, class CoType>
00237 void ABA_ACTIVE<BaseType, CoType>::insert(ABA_POOLSLOT<BaseType, CoType> *ps)
00238 {
00239 #ifdef ABACUSSAFE
00240 if (n_ == max()) {
00241 master_->err() << "ABA_ACTIVE::insert(): buffer is full" << endl;
00242 exit (Fatal);
00243 }
00244 #endif
00245
00246 active_[n_] = new ABA_POOLSLOTREF<BaseType, CoType>(ps);
00247 redundantAge_[n_] = 0;
00248 n_++;
00249 }
00250
00251 template <class BaseType, class CoType>
00252 void ABA_ACTIVE<BaseType, CoType>::insert(
00253 ABA_BUFFER<ABA_POOLSLOT<BaseType, CoType> *> &ps)
00254 {
00255 const int nPs = ps.number();
00256
00257 for(int i = 0; i < nPs; i++)
00258 insert(ps[i]);
00259 }
00260
00261 template <class BaseType, class CoType>
00262 void ABA_ACTIVE<BaseType, CoType>::remove(ABA_BUFFER<int> &del)
00263 {
00264 const int nDel = del.number();
00265
00266 for(int i = 0; i < nDel; i++)
00267 delete active_[del[i]];
00268 active_.leftShift(del);
00269 redundantAge_.leftShift(del);
00270 n_ -= nDel;
00271 }
00272
00273 template <class BaseType, class CoType>
00274 void ABA_ACTIVE<BaseType, CoType>::realloc(int newSize)
00275 {
00276 active_.realloc(newSize);
00277 redundantAge_.realloc(newSize);
00278 }
00279
00280 template <class BaseType, class CoType>
00281 inline int ABA_ACTIVE<BaseType, CoType>::redundantAge(int i) const
00282 {
00283 return redundantAge_[i];
00284 }
00285
00286 template <class BaseType, class CoType>
00287 inline void ABA_ACTIVE<BaseType, CoType>::incrementRedundantAge(int i)
00288 {
00289 redundantAge_[i]++;
00290 }
00291
00292 template <class BaseType, class CoType>
00293 inline void ABA_ACTIVE<BaseType, CoType>::resetRedundantAge(int i)
00294 {
00295 redundantAge_[i] = 0;
00296 }
00297
00298 #endif // ABA_ACTIVE_INC