Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

hash_types.H

Go to the documentation of this file.
00001 
00002 #ifndef HASH_TYPES_H_INCLUDED
00003 #define HASH_TYPES_H_INCLUDED
00004 
00005 /* ------------------- Hash table variables ----------------------------- */
00006 
00007 class   HASHobs;
00008 class   hashdist;
00009 typedef ARRAYptrs<HASHobs *> HASHobs_list;
00010 class HASHobs {
00011    static HASHobs_list  *_hash_obs_list;
00012    HASHobs_list *hash_list()     { if (!_hash_obs_list) 
00013                                       _hash_obs_list = new HASHobs_list;
00014                                    return _hash_obs_list; }
00015    public:
00016    virtual ~HASHobs() {}
00017    static  void notify_hash_obs(CGELptr &o, hashdist *h)
00018                                  { if (!_hash_obs_list) return;
00019                                    for (int i=0;i<_hash_obs_list->num();i++) 
00020                                      (*_hash_obs_list)[i]->notify_hash(o,h); }
00021    virtual void notify_hash(CGELptr &old, hashdist *h) = 0;
00022    
00023            void hash_obs()       { hash_list()->add_uniquely(this); }
00024            void unobs_hash()     { hash_list()->rem         (this); }
00025 };
00026 
00027 class hashdist : public DATA_ITEM, public GELdistobs,
00028                  public EXISTobs,   public DUPobs {
00029    protected:
00030       str_ptr   _str;  // name of the hash variable
00031       const int _dist; // whether this hash variable should be distributed
00032       HASH      _dhash;// hash table of objects that have non-default value
00033       const int _dup;  // ... should be copied on object duplication
00034       TAGlist   _tags;
00035               void *find(CGELptr &g)  const   { return _dhash.find((long) &*g);}
00036               void  add (CGELptr &g, void *v) { _dhash.add((long) &*g, v); }
00037       virtual void  del_item(void *) = 0;
00038               void  del_hash_items()          { ARRAY<long  > keys;
00039                                                 ARRAY<void *> items;
00040                                                 _dhash.get_items(keys, items);
00041                                                 for (int i=0; i<keys.num();i++){
00042                                                    _dhash.del(keys[i]);
00043                                                    del_item(items[i]);
00044                                                 }
00045                                               }
00046    public:
00047       virtual        ~hashdist()   { }
00048                       hashdist(Cstr_ptr &str, int dist, int dup=1):_str(str),
00049                                        _dist(dist), _dhash(16), _dup(dup) {
00050                          if (_dist)   // if hash is distributed, we watch
00051                             distrib_obs(); // when any GEL is distributed
00052                          DATA_ITEM::add_decoder(_str, this);
00053                          exist_obs(); // deleted objects must be uhashed
00054                          if (_dup)    // If 1-to-1 mapping, we don't want to
00055                             dup_obs();// copy information when object is dup'ed
00056                          _tags += new TAG_meth<hashdist>("",
00057                                &hashdist::put_dummy, &hashdist::get_var, 1);
00058                        }
00059              void      del(CGELptr &g)              { void *ret = 0;
00060                                                       if ((ret=find(g))) {
00061                                                          _dhash.del((long) &*g);
00062                                                          del_item(ret); }
00063                                                     }
00064               int       is_default(CGELptr &g)const { return find(g)==0; }
00065               CHASH    &hash()                const { return _dhash; }
00066       virtual CTAGlist &tags()                const { return _tags; }
00067       virtual DATA_ITEM *dup()                const { return  0; }
00068       virtual STAT_STR_RET class_name ()      const { return _str; }
00069       virtual void     put_dummy(TAGformat &) const { }  // unused
00070       virtual void     get_var  (TAGformat &)     = 0;
00071       virtual void     notify_exist(CGELptr &g, int f) { if (!f) del(g); }
00072       virtual void     notify_dup  (CGELptr &old,CGELptr &newg) = 0;
00073       virtual void     put_var(TAGformat &d,  CGELptr &g) const=0;
00074       virtual void     notify_distrib(STDdstream &ds,CGELptr&g) {
00075                                TAGformat d(&ds,class_name(),1); put_var(d,g);}
00076 };
00077 
00078 template <class T>
00079 class hashvar : public hashdist {
00080    T       _val;                 // default value of hash variable
00081    virtual void del_item(void * item) { delete (TDI<T> *) item;}
00082   public :
00083                  hashvar(Cstr_ptr &var, T val, int dist=0, int dup=1):
00084                       hashdist(var,dist,dup), _val(val) {}
00085    virtual      ~hashvar()         { del_hash_items();} // Can't do in ~hashdist
00086 
00087            T     get(CGELptr &g) const { return find(g) ? 
00088                                             ((TDI<T> *)find(g))->get() : _val; }
00089            void  set(GELptr g, T v)     { del(g);
00090                                           add(g, (void *)new TDI<T>(v));
00091                                           if (_dist)
00092                                           HASHobs::notify_hash_obs(g,this); }
00093    virtual void notify_dup(CGELptr &old, CGELptr &newg)
00094                                           { if (find(old)) set(newg, get(old));}
00095    virtual void put_var(TAGformat &d, CGELptr &g) const {
00096                                             if (_dist && find(g)) {
00097                                               d.id() << g->name() << get(g); 
00098                                               d.end_id();} }
00099    virtual void get_var(TAGformat &d)     { GELptr  g;
00100                                             T       inval;
00101                                             *d >> g >> inval; 
00102                                             if (g) set(g, inval); }
00103 };
00104 
00105 // (AIX compiler seems to create a macro called Free(p), so this is necessary)
00106 #ifdef Free
00107 #undef Free
00108 #endif
00109 template <class T>
00110 class hashptr : public hashdist {
00111    T       _val;                 // default value of hash variable
00112    virtual void del_item(void *item) { ((T) item)->Free(); }
00113   public :
00114                 hashptr(Cstr_ptr &var, const T v, int dist=0,int dup=1):
00115                       hashdist(var,dist,dup), _val(v) { if (v) v->Own(); }
00116                ~hashptr()          { del_hash_items();} // Can't do in ~hashdist
00117            T    get(CGELptr &g)    { return find(g) ? (T)find(g) : _val;}
00118            void set(GELptr g, T v) { if (v) v->Own(); 
00119                                             del(g); add(g, (void *)v);
00120                                             if (_dist)
00121                                             HASHobs::notify_hash_obs(g,this); }
00122 
00123                          // Don't know about serializing of pointers
00124    virtual void put_var     (TAGformat &, CGELptr&) const { }
00125    virtual void get_var     (TAGformat &)                 { }
00126    virtual void notify_exist(CGELptr &g, int f)           { if (!f&&g) del(g);}
00127    virtual void notify_dup  (CGELptr &old, CGELptr &newg) { if (find(old)) 
00128                                                            set(newg, get(old));}
00129 };
00130 
00131 template <class T>
00132 class hashenum : public hashdist {
00133    T       _val;                 // default value of hash variable
00134    virtual void del_item(void *item) { delete ((TDI<int> *) item); }
00135   public :
00136                 hashenum(Cstr_ptr &var, T val, int dist=0, int dup=0):
00137                          hashdist(var,dist,dup), _val(val) {}
00138                ~hashenum()         { del_hash_items();} // Can't do in ~hashdist
00139            T    get(CGELptr &g) const { return (T)(find(g) ? 
00140                                           ((TDI<int> *)find(g))->get() : _val);}
00141            void set(GELptr g, T v)    { del(g);
00142                                         add(g, (void *) new TDI<int>((int)v));
00143                                         if (_dist)
00144                                             HASHobs::notify_hash_obs(g,this); }
00145    
00146     // 2005 VS generates compiler warnings for this funcion          
00147    //virtual str_ptr enum_to_str(T e) const { char b[20];sprintf(b,"%d",(int)e); 
00148    //                                         return b; }
00149    virtual T    str_to_enum(Cstr_ptr &s) const { return (T)atoi(**s); }
00150    virtual void put_var(TAGformat &d, CGELptr &gel) const {
00151                                         if (class_name() && find(gel)) {
00152                                            d.id() << gel->name() << " " << get(gel);
00153                                            d.end_id(); } 
00154                                        }
00155    virtual void get_var(TAGformat &d)  {  GELptr g; str_ptr val;
00156                                          *d >> g >> val; 
00157                                          if (g) set(g, str_to_enum(val)); }
00158 
00159    virtual void notify_dup(CGELptr &old, CGELptr &newg)
00160                                        { if (find(old)) set(newg, get(old)); }
00161 };
00162 
00163 
00164 class GrabVar : public hashvar<int> {
00165   public :
00166    GrabVar() : hashvar<int>("GRABBED", 0, 0) { }
00167            void grab      (CGELptr &g) { set(g, get(g)+1); GRABobs::notify_grab_obs(g,1); }
00168            void release   (CGELptr &g) { set(g, get(g)-1); GRABobs::notify_grab_obs(g,0); }
00169    virtual void notify_dup(CGELptr &, CGELptr &) { }
00170 };
00171 
00172 
00173 #define MAKE_NET_HASHVAR(NAME, TYPE, VAL) hashvar<TYPE>  NAME(#NAME, VAL, 1)
00174 #define MAKE_NET_HASHENUM(NAME,TYPE, VAL) hashenum<TYPE> NAME(#NAME, VAL, 1)
00175 #endif

Generated on Mon Sep 18 11:39:31 2006 for jot by  doxygen 1.4.4