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
00028 #ifndef _SPLIT_DELTA_H_
00029 #define _SPLIT_DELTA_H_
00030
00031 #include <api_delta.h>
00032 #include <bound_delta.h>
00033
00034 namespace coco {
00035
00037
00042 class split_undelta : public undelta_base
00043 {
00044 private:
00047 work_node::transaction_number se;
00048
00049 public:
00051 split_undelta(const work_node::transaction_number& _se) : se(_se) {}
00052
00054 split_undelta(const split_undelta& _su) : se(_su.se)
00055 {
00056 #if DEBUG_DELTA
00057 std::cerr << "Called split_undelta copy constructor" << std::endl;
00058 #endif
00059 }
00060
00062 virtual ~split_undelta() {}
00063
00065 split_undelta* new_copy() const { return new split_undelta(*this); }
00067 void destroy_copy(undelta_base* __d) const { delete (split_undelta*)__d; }
00068
00070 bool unapply(work_node& x, const delta_id& _did) const;
00071 };
00072
00074
00079 class split_delta : public delta_base
00080 {
00081 public:
00085 std::list<std::vector<delta> > splits;
00086
00087
00088
00089 public:
00091 split_delta() : delta_base("split"), splits() {}
00092
00093
00094
00095
00096
00101 split_delta(unsigned int _node_num, const interval& _l, const interval& _u)
00102 : delta_base("split"), splits()
00103 {
00104 splits.push_back(std::vector<delta>(1,
00105 delta(bound_delta(_node_num, _l))));
00106 splits.push_back(std::vector<delta>(1,
00107 delta(bound_delta(_node_num, _u))));
00108 }
00109
00114 split_delta(unsigned int _node_num, const std::vector<interval>& _m)
00115 : delta_base("split"), splits()
00116 {
00117 for(std::vector<interval>::const_iterator __l = _m.begin();
00118 __l != _m.end(); ++__l)
00119 {
00120 splits.push_back(std::vector<delta>(1,
00121 delta(bound_delta(_node_num, *__l))));
00122 }
00123 }
00124
00129 split_delta(const std::vector<unsigned int>& _i,
00130 const std::vector<interval>& _l, const std::vector<interval>& _u)
00131 : delta_base("split"), splits()
00132 {
00133 splits.push_back(std::vector<delta>(1,delta(bound_delta(_i, _l))));
00134 splits.push_back(std::vector<delta>(1,delta(bound_delta(_i, _u))));
00135 }
00136
00138 split_delta(const std::list<std::vector<delta> >& __dl)
00139 : delta_base("split"), splits(__dl)
00140 {}
00141
00147 split_delta(const std::vector<unsigned int> nnum,
00148 const std::vector<std::pair<interval,interval> >& bds)
00149 : delta_base("split"), splits()
00150 { add_multisplit(nnum, bds); }
00151
00156 split_delta(const std::vector<unsigned int> nnum,
00157 const std::vector<std::vector<interval> >& bds)
00158 : delta_base("split"), splits()
00159 { add_multisplit(nnum, bds); }
00160
00162 ~split_delta() {}
00163
00165 split_delta(const split_delta& __s) : delta_base(__s), splits(__s.splits) {}
00166
00168 split_delta* new_copy() const { return new split_delta(*this); }
00170 void destroy_copy(delta_base* __d) const { delete (split_delta*)__d; }
00171
00174 void add_delta(const delta& __d)
00175 {
00176 splits.push_back(std::vector<delta>(1,__d));
00177 }
00178
00181 void add_deltas(const std::vector<delta>& __d)
00182 {
00183 splits.push_back(__d);
00184 }
00187 void add_split(const std::vector<unsigned int>& _i,
00188 const std::vector<interval>& _b)
00189 {
00190 splits.push_back(std::vector<delta>(1,delta(bound_delta(_i, _b))));
00191 }
00192
00193
00197 void add_split(unsigned int _nnum, interval _b)
00198 {
00199 splits.push_back(std::vector<delta>(1,delta(bound_delta(_nnum, _b))));
00200 }
00201
00206 void add_split(unsigned int _nnum, interval _l, interval _u)
00207 {
00208 splits.push_back(std::vector<delta>(1,delta(bound_delta(_nnum, _l))));
00209 splits.push_back(std::vector<delta>(1,delta(bound_delta(_nnum, _u))));
00210 }
00211
00216 void add_split(const std::vector<unsigned int>& _i,
00217 const std::vector<interval>& _l,
00218 const std::vector<interval>& _u)
00219 {
00220 splits.push_back(std::vector<delta>(1,delta(bound_delta(_i, _l))));
00221 splits.push_back(std::vector<delta>(1,delta(bound_delta(_i, _u))));
00222 }
00223
00228 void add_multisplit(const std::vector<unsigned int> nnum,
00229 const std::vector<std::pair<interval,interval> >& bds);
00230
00234 void add_multisplit(const std::vector<unsigned int> nnum,
00235 const std::vector<std::vector<interval> >& bds);
00236
00239 bool apply(work_node& x, undelta_base*& _u, const delta_id& _did) const;
00240
00242 bool operator==(const delta_base& _c) const
00243 { return _c.get_action() == get_action() &&
00244 this->operator==(*(split_delta*)&_c); }
00245 bool operator!=(const delta_base& _c) const
00246 { return _c.get_action() != get_action() ||
00247 this->operator!=(*(split_delta*)&_c); }
00248
00250 bool operator==(const split_delta& _c) const
00251 { return this == &_c || splits == _c.splits; }
00252 bool operator!=(const split_delta& _c) const
00253 { return this != &_c && splits != _c.splits; }
00254 };
00255
00256 inline bool split_undelta::unapply(work_node& x, const delta_id& _did) const
00257 {
00258 std::map<work_node::transaction_number,
00259 std::list<std::vector<delta> > >::iterator _f;
00260 x.split_delta_ids.erase(_did);
00261 _f = x.proposed_splits.find(se);
00262 if(_f != x.proposed_splits.end())
00263 {
00264 x.proposed_splits.erase(_f);
00265 return true;
00266 }
00267 else
00268 return false;
00269 }
00270
00271 inline bool split_delta::apply(work_node& x, undelta_base*& _u,
00272 const delta_id& _did) const
00273 {
00274 work_node::transaction_number se(x.get_transaction_number());
00275 x.proposed_splits.insert(std::make_pair(se,splits));
00276 x.split_delta_ids[_did] = se;
00277 _u = (undelta_base*) new split_undelta(se);
00278 return true;
00279 }
00280
00285 inline void split_delta::add_multisplit(const std::vector<unsigned int> nnum,
00286 const std::vector<std::pair<interval,interval> >& bds)
00287 {
00288 unsigned int vns(nnum.size());
00289 if(bds.size() != vns)
00290 throw api_exception(apiee_delta,
00291 "split_delta::add_splits: nnum and bds have different lengths");
00292 std::vector<bool> v_bool(vns, false);
00293 std::vector<interval> v_bnds(vns);
00294
00295 bool all_and;
00296 do
00297 {
00298 all_and = true;
00299 for(unsigned int i = 0; i < vns; ++i)
00300 {
00301 if(v_bool[i])
00302 v_bnds[i] = bds[i].second;
00303 else
00304 {
00305 v_bnds[i] = bds[i].first;
00306 if(all_and)
00307 {
00308 all_and = false;
00309 v_bool[i] = true;
00310 for(unsigned int j = 0; j < i; ++j) v_bool[j] = false;
00311 }
00312 }
00313 }
00314 splits.push_back(std::vector<delta>(1,delta(bound_delta(nnum, v_bnds))));
00315 }
00316 while(!all_and);
00317 }
00318
00319 inline void split_delta::add_multisplit(const std::vector<unsigned int> nnum,
00320 const std::vector<std::vector<interval> >& bds)
00321 {
00322 unsigned int vns(nnum.size());
00323 unsigned int hidx;
00324 if(bds.size() != vns)
00325 throw api_exception(apiee_delta,
00326 "split_delta::add_splits: nnum and bds have different lengths");
00327 std::vector<unsigned int> v_idx(vns, 0);
00328 std::vector<interval> v_bnds(vns);
00329
00330 while(1)
00331 {
00332 for(unsigned int i; i < vns; ++i)
00333 v_bnds[i] = bds[i][v_idx[i]];
00334 splits.push_back(std::vector<delta>(1,delta(bound_delta(nnum, v_bnds))));
00335
00336 for(hidx = 0; hidx < vns; hidx++)
00337 {
00338 v_idx[hidx]++;
00339 if(v_idx[hidx] == bds[hidx].size())
00340 v_idx[hidx] = 0;
00341 else
00342 break;
00343 }
00344 if(hidx == vns)
00345 break;
00346 }
00347 }
00348
00349 }
00350
00351 #endif