Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:14

0001 #pragma once
0002 
0003 #include "s_pool.h"
0004 #include <iomanip>
0005 
0006 struct Obj ; 
0007 
0008 /**
0009 _Obj : persistable type must not have any pointers 
0010 **/
0011 struct _Obj
0012 {
0013     int type ;  
0014     int left ; 
0015     int right ; 
0016     int parent ; 
0017 
0018     std::string desc() const ; 
0019 };
0020 inline std::string _Obj::desc() const 
0021 {
0022     std::stringstream ss ; 
0023     ss << "_Obj::desc " 
0024        << " type " << std::setw(5) << type 
0025        << " left " << std::setw(5) << left 
0026        << " right " << std::setw(5) << right 
0027        << " parent " << std::setw(5) << parent 
0028        ; 
0029     std::string str = ss.str(); 
0030     return str ; 
0031 }
0032 
0033 
0034 /**
0035 Obj : ctor/dtor instrumented with pool.add(this)/pool.remove(this) 
0036 **/
0037 
0038 struct Obj 
0039 {
0040     typedef s_pool<Obj, _Obj> POOL ;
0041     static POOL* pool ;
0042 
0043     static int Level(); 
0044     static Obj* Lookup(  int pid);  
0045     static Obj* GetByIdx(int idx);  
0046     static int Index(const Obj* o);
0047   
0048     int idx() const ; 
0049     std::string desc() const ; 
0050 
0051     Obj( int type, Obj* left=nullptr, Obj* right=nullptr ); 
0052     ~Obj();  
0053 
0054     static std::string Desc(const Obj* o); 
0055     static void Serialize(    _Obj& p, const Obj* o ); 
0056     static Obj* Import( const _Obj* p, const std::vector<_Obj>& buf ); 
0057     static Obj* Import_r( const _Obj* p, const std::vector<_Obj>& buf ); 
0058 
0059     int   pid ;   // HMM: not required, but useful for debug   
0060     int   type ; 
0061     Obj*  left ; 
0062     Obj*  right ; 
0063     Obj*  parent ; 
0064 };
0065 
0066 inline int  Obj::Level() {  return ssys::getenvint("Obj__level",-1) ; } // static 
0067 inline Obj* Obj::Lookup(  int pid){ return pool->lookup(pid) ; } // static
0068 inline Obj* Obj::GetByIdx(int idx){ return pool->getbyidx(idx) ; } // static
0069 inline int Obj::Index(const Obj* o){ return pool ? pool->index(o) : -1 ; } // static
0070 
0071 inline int Obj::idx() const { return Index(this); } 
0072 
0073 
0074 inline std::string Obj::desc() const
0075 {
0076     std::stringstream ss ;
0077     ss << "Obj::desc"
0078        << " pid " << pid
0079        << " type " << type 
0080        ; 
0081     std::string str = ss.str(); 
0082     return str ; 
0083 
0084 }
0085 
0086 inline Obj::Obj( int type_, Obj* left_, Obj* right_ )
0087     :
0088     pid(pool->add(this)),
0089     type(type_),
0090     left(left_),
0091     right(right_)
0092 {
0093     if(Level()>1) std::cout << "[ Obj::Obj pid " << pid << "\n" ; 
0094 
0095     if( left && right )
0096     {
0097         left->parent = this ; 
0098         right->parent = this ; 
0099     }
0100 
0101     if(Level()>1) std::cout << "] Obj::Obj pid " << pid << "\n" ; 
0102 }
0103 
0104 /**
0105 Obj dtor
0106 ----------
0107 
0108 As Obj does recursive deletion it means that should be creating Obj 
0109 onto heap (not stack) for control, 
0110 using things like std::vector<Obj> will cause double dtors 
0111 
0112 **/
0113 
0114 inline Obj::~Obj()
0115 {
0116     if(Level()>1) std::cout << "[ Obj::~Obj pid " << pid << "\n" ; 
0117     delete left ; 
0118     delete right ; 
0119 
0120     pool->remove(this) ; 
0121     if(Level()>1) std::cout << "] Obj::~Obj pid " << pid << "\n" ; 
0122 }
0123 
0124 
0125 inline std::string Obj::Desc(const Obj* o)
0126 {
0127     return o ? o->desc() : "-" ; 
0128 }
0129 
0130 
0131 /**
0132 Obj::Serialize
0133 -----------------
0134  
0135 **/
0136 
0137 inline void Obj::Serialize( _Obj& p, const Obj* o ) // static
0138 {
0139     p.type   = o->type ; 
0140     p.left   = pool->index(o->left);  
0141     p.right  = pool->index(o->right);  
0142     p.parent = pool->index(o->parent);  
0143 
0144     std::cerr << "Obj::Serialize p " << p.desc() << std::endl ; 
0145 }
0146 /**
0147 Obj::Import
0148 -----------------
0149 
0150 HMM: when the Obj are arranged into one or more trees 
0151 its easiest to import recursively by the roots, so need
0152 a way to identify the roots from the persisted _Obj type.  
0153 Simple way to do that is with parent links that are -1 
0154 for roots. 
0155  
0156 **/
0157 
0158 inline Obj* Obj::Import( const _Obj* p, const std::vector<_Obj>& buf ) // static
0159 {
0160     std::cerr << "Obj::Import " << p->desc() << std::endl ; 
0161     Obj* root = nullptr ; 
0162     if(p->parent == -1) root = Import_r(p, buf); 
0163     return root ; 
0164 }
0165 
0166 /**
0167 Obj::Import_r
0168 --------------
0169 
0170 Separating recursive parts of the import from the root parts is clearer.
0171 
0172 **/
0173 
0174 inline Obj* Obj::Import_r( const _Obj* p, const std::vector<_Obj>& buf )
0175 {
0176     if(p == nullptr) return nullptr ; 
0177 
0178     std::cerr << "Obj::Import_r " << p->desc() << std::endl ; 
0179 
0180     int type = p->type ;  
0181     const _Obj* _left  = p->left  > -1 ? &buf[p->left]  : nullptr ;  
0182     const _Obj* _right = p->right > -1 ? &buf[p->right] : nullptr ;  
0183 
0184     Obj* left  = Import_r( _left , buf ); 
0185     Obj* right = Import_r( _right, buf ); 
0186     Obj* node  = new Obj( type, left, right ); 
0187     return node ; 
0188 }
0189 
0190