Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/wroot/free_seg

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_wroot_free_seg
  5 #define tools_wroot_free_seg
  6 
  7 #include "seek"
  8 #include "wbuf"
  9 #include "../forit"
 10 
 11 #include <ostream>
 12 
 13 namespace tools {
 14 namespace wroot {
 15 
 16 class free_seg {
 17 public:
 18   free_seg(std::ostream& a_out,seek a_first,seek a_last)
 19   :m_out(a_out),m_first(a_first),m_last(a_last){}
 20   virtual ~free_seg(){}
 21 public:
 22   free_seg(const free_seg& a_from)
 23   :m_out(a_from.m_out),m_first(a_from.m_first),m_last(a_from.m_last)
 24   {}
 25   free_seg& operator=(const free_seg& a_from){
 26     m_first = a_from.m_first;
 27     m_last = a_from.m_last;
 28     return *this;
 29   }
 30 public:
 31   std::ostream& out() const {return m_out;}
 32 
 33   seek first() const {return m_first;}
 34   seek last() const {return m_last;}
 35 
 36   void set_first(seek a_v) {m_first = a_v;}
 37   void set_last(seek a_v) {m_last = a_v;}
 38 
 39   unsigned int record_size() const {
 40     //GB if(fLast>RIO_START_BIG_FILE) {
 41     if((m_first>START_BIG_FILE())|| //GB
 42        (m_last>START_BIG_FILE()) ){
 43       return sizeof(short) +  2 * sizeof(seek);
 44     } else {
 45       return sizeof(short) +  2 * sizeof(seek32);
 46     }
 47   }
 48 
 49   bool fill_buffer(wbuf& a_wb) {
 50     short version = 1;
 51 
 52     //GB if(fLast>START_BIG_FILE()) version += big_file_version_tag();
 53     if((m_first>START_BIG_FILE())||
 54        (m_last>START_BIG_FILE())) version += big_file_version_tag();
 55 
 56     if(!a_wb.write(version)) return false;
 57 
 58     if(version>(short)big_file_version_tag()) {
 59       if(!a_wb.write(m_first)) return false;
 60       if(!a_wb.write(m_last)) return false;
 61     } else {
 62       if(m_first>START_BIG_FILE()) { //GB
 63         m_out << "tools::wroot::free_seg::fill_buffer :"
 64              << " attempt to write big Seek "
 65              << m_first << " on 32 bits."
 66              << std::endl;
 67         return false;
 68       }
 69       if(!a_wb.write((seek32)m_first)) return false;
 70       if(m_last>START_BIG_FILE()) { //GB
 71         m_out << "tools::wroot::free_seg::fill_buffer :"
 72              << " attempt to write big seek "
 73              << m_last << " on 32 bits."
 74              << std::endl;
 75         return false;
 76       }
 77       if(!a_wb.write((seek32)m_last)) return false;
 78     }
 79 
 80     return true;
 81   }
 82 
 83 protected:
 84   std::ostream& m_out;
 85   seek m_first;  //First free word of segment
 86   seek m_last;   //Last free word of segment
 87 };
 88 
 89 }}
 90 
 91 #include <list>
 92 
 93 namespace tools {
 94 namespace wroot {
 95 
 96 inline free_seg* find_after(const std::list<free_seg*>& a_list,free_seg* a_what) {
 97   tools_lforcit(free_seg*,a_list,it) {
 98     if((*it)==a_what) {
 99       it++;
100       if(it==a_list.end()) return 0;
101       return *it;
102     }
103   }
104   return 0;
105 }
106 
107 inline void remove(std::list<free_seg*>& a_list,free_seg* a_what) {
108   //NOTE : it does not delete a_what.
109   tools_lforit(free_seg*,a_list,it) {
110     if((*it)==a_what) {
111       a_list.erase(it);
112       return;
113     }
114   }
115 }
116 
117 inline void add_before(std::list<free_seg*>& a_list,free_seg* a_what,free_seg* a_new) {
118   tools_lforit(free_seg*,a_list,it) {
119     if((*it)==a_what) {
120       a_list.insert(it,a_new);
121       return;
122     }
123   }
124 }
125 
126 inline free_seg* add_free(std::list<free_seg*>& a_list,seek a_first,seek a_last) {
127   // Add a new free segment to the list of free segments
128   // ===================================================
129   //  If last just preceedes an existing free segment, then first becomes
130   //     the new starting location of the free segment.
131   //  if first just follows an existing free segment, then last becomes
132   //     the new ending location of the free segment.
133   //  if first just follows an existing free segment AND last just preceedes
134   //     an existing free segment, these two segments are merged into
135   //     one single segment.
136   //
137 
138   free_seg* idcur = a_list.front();
139 
140   while (idcur) {
141     seek curfirst = idcur->first();
142     seek curlast  = idcur->last();
143     if (curlast == (a_first-1)) {
144       idcur->set_last(a_last);
145       free_seg* idnext = find_after(a_list,idcur);
146       if (idnext == 0) return idcur;
147       if (idnext->first() > (a_last+1)) return idcur;
148       idcur->set_last(idnext->last());
149       remove(a_list,idnext); //idnext not deleted.
150       delete idnext;
151       return idcur;
152     }
153     if (curfirst == (a_last+1)) {
154       idcur->set_first(a_first);
155       return idcur;
156     }
157     if (a_first < curfirst) {
158       free_seg* newfree = new free_seg(idcur->out(),a_first,a_last);
159       add_before(a_list,idcur,newfree);
160       return newfree;
161     }
162     idcur = find_after(a_list,idcur);
163   }
164 
165   return 0;
166 }
167 
168 
169 }}
170 
171 #endif