00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <Basics.H>
00024 #include <FS.H>
00025 #include <VestaLog.H>
00026 #include <Recovery.H>
00027
00028 #include "IntIntTblLR.H"
00029
00030 using std::istream;
00031 using std::ostream;
00032 using std::endl;
00033
00034
00035 static const short Unused = -1;
00036
00037 IntIntTblLR::IntIntTblLR(int sizeHint) throw ()
00038 : numEntries(0), eltLen(sizeHint)
00039 {
00040 if (sizeHint > 0) {
00041 this->elt = NEW_PTRFREE_ARRAY(short, sizeHint);
00042 for (int i = 0; i < this->eltLen; i++) {
00043 this->elt[i] = Unused;
00044 }
00045 } else {
00046 assert(sizeHint == 0);
00047 this->elt = (short *)NULL;
00048 }
00049 }
00050
00051 IntIntTblLR::IntIntTblLR(const IntIntTblLR *tbl) throw ()
00052 : numEntries(tbl->numEntries), eltLen(tbl->eltLen)
00053 {
00054 if (this->eltLen > 0) {
00055 this->elt = NEW_PTRFREE_ARRAY(short, this->eltLen);
00056 int numUsed = 0;
00057 for (int i = 0; i < this->eltLen; i++) {
00058 this->elt[i] = tbl->elt[i];
00059 if (tbl->elt[i] != Unused) numUsed++;
00060 }
00061 assert(numUsed == this->numEntries);
00062 } else {
00063 assert(this->eltLen == 0 && this->numEntries == 0);
00064 this->elt = (short *)NULL;
00065 }
00066 }
00067
00068 bool IntIntTblLR::Get(short k, short& v) const throw ()
00069 {
00070 bool res;
00071 if (k < this->eltLen && this->elt != (short *)NULL) {
00072 short val = this->elt[k];
00073 res = (val != Unused);
00074 if (res) v = val;
00075 } else {
00076 res = false;
00077 }
00078 return res;
00079 }
00080
00081 bool IntIntTblLR::Put(short k, short v) throw ()
00082 {
00083 bool res;
00084
00085 if (k < this->eltLen && this->elt != (short *)NULL) {
00086
00087 res = (this->elt[k] != Unused);
00088 if (!res) this->numEntries++;
00089 } else {
00090
00091 int oldEltLen = this->eltLen;
00092 this->eltLen = max(k+1, oldEltLen+10);
00093 short *newElt = NEW_PTRFREE_ARRAY(short, this->eltLen);
00094 if (this->elt != (short *)NULL) {
00095
00096 int i;
00097 for (i = 0; i < oldEltLen; i++) {
00098 newElt[i] = this->elt[i];
00099 }
00100 for (; i < this->eltLen; i++) {
00101 newElt[i] = Unused;
00102 }
00103 } else {
00104
00105 for (int i = 0; i < this->eltLen; i++) {
00106 newElt[i] = Unused;
00107 }
00108 }
00109 this->elt = newElt;
00110 this->numEntries++;
00111 res = false;
00112 }
00113 this->elt[k] = v;
00114 return res;
00115 }
00116
00117 bool IntIntTblLR::Delete(short k, short& v) throw ()
00118 {
00119 bool res;
00120 if (k < this->eltLen && this->elt != (short *)NULL
00121 && this->elt[k] != Unused) {
00122 v = this->elt[k];
00123 this->elt[k] = Unused;
00124 this->numEntries--;
00125 res = true;
00126 } else {
00127 res = false;
00128 }
00129 return res;
00130 }
00131
00132 void IntIntTblLR::Log(VestaLog& log) const
00133 throw (VestaLog::Error)
00134 {
00135 log.write((char *)(&(this->numEntries)), sizeof(this->numEntries));
00136 log.write((char *)(&(this->eltLen)), sizeof(this->eltLen));
00137 if (this->numEntries > 0) {
00138 int numWritten = 0;
00139 for (short k = 0; k < this->eltLen; k++) {
00140 if (this->elt[k] != Unused) {
00141 log.write((char *)(&k), sizeof(k));
00142 log.write((char *)(&(this->elt[k])), sizeof(this->elt[k]));
00143 numWritten++;
00144 }
00145 }
00146 assert(numWritten == this->numEntries);
00147 }
00148 }
00149
00150 void IntIntTblLR::Recover(RecoveryReader &rd)
00151 throw (VestaLog::Error, VestaLog::Eof)
00152
00153
00154
00155
00156
00157
00158
00159 {
00160 rd.readAll((char *)(&(this->numEntries)), sizeof(this->numEntries));
00161 rd.readAll((char *)(&(this->eltLen)), sizeof(this->eltLen));
00162 if (this->numEntries > 0) {
00163 short nextToWrite = 0;
00164 this->elt = NEW_PTRFREE_ARRAY(short, this->eltLen);
00165
00166
00167 for (int i = 0; i < this->numEntries; i++) {
00168 short k;
00169 rd.readAll((char *)(&k), sizeof(k));
00170
00171 assert(k >= nextToWrite);
00172 while (nextToWrite < k) {
00173 this->elt[nextToWrite++] = Unused;
00174 }
00175 assert(k < this->eltLen);
00176 rd.readAll((char *)(&(this->elt[k])), sizeof(this->elt[k]));
00177 nextToWrite++;
00178 }
00179
00180 while (nextToWrite < this->eltLen) {
00181 this->elt[nextToWrite++] = Unused;
00182 }
00183 } else {
00184 this->elt = (short *)NULL;
00185 }
00186 }
00187
00188 void IntIntTblLR::Write(ostream &ofs) const
00189 throw (FS::Failure)
00190 {
00191 FS::Write(ofs, (char *)(&(this->numEntries)), sizeof(this->numEntries));
00192 FS::Write(ofs, (char *)(&(this->eltLen)), sizeof(this->eltLen));
00193 if (this->numEntries > 0) {
00194 int numWritten = 0;
00195 for (short k = 0; k < this->eltLen; k++) {
00196 if (this->elt[k] != Unused) {
00197 FS::Write(ofs, (char *)(&k), sizeof(k));
00198 FS::Write(ofs, (char *)(&(this->elt[k])), sizeof(this->elt[k]));
00199 numWritten++;
00200 }
00201 }
00202 assert(numWritten == this->numEntries);
00203 }
00204 }
00205
00206 void IntIntTblLR::Read(istream &ifs)
00207 throw (FS::EndOfFile, FS::Failure)
00208
00209
00210
00211
00212
00213
00214
00215 {
00216 FS::Read(ifs, (char *)(&(this->numEntries)), sizeof(this->numEntries));
00217 FS::Read(ifs, (char *)(&(this->eltLen)), sizeof(this->eltLen));
00218 if (this->numEntries > 0) {
00219 short nextToWrite = 0;
00220 this->elt = NEW_PTRFREE_ARRAY(short, this->eltLen);
00221
00222
00223 for (int i = 0; i < this->numEntries; i++) {
00224 short k;
00225 FS::Read(ifs, (char *)(&k), sizeof(k));
00226
00227 assert(k >= nextToWrite);
00228 while (nextToWrite < k) {
00229 this->elt[nextToWrite++] = Unused;
00230 }
00231 assert(k < this->eltLen);
00232 FS::Read(ifs, (char *)(&(this->elt[k])), sizeof(this->elt[k]));
00233 nextToWrite++;
00234 }
00235
00236 while (nextToWrite < this->eltLen) {
00237 this->elt[nextToWrite++] = Unused;
00238 }
00239 } else {
00240 this->elt = (short *)NULL;
00241 }
00242 }
00243
00244 inline void Indent(ostream &os, int indent) throw ()
00245 {
00246 for (int i = 0; i < indent; i++) os << " ";
00247 }
00248
00249 void IntIntTblLR::Print(ostream &os, int indent) const throw ()
00250 {
00251 const int NumPerLine = 7;
00252 int cnt = 0;
00253 os << "{ ";
00254 for (short k = 0; cnt < this->numEntries; k++) {
00255 short v;
00256 if (this->Get(k, v)) {
00257 if (cnt > 0) os << ", ";
00258 if (cnt % NumPerLine == 0) {
00259 os << endl; Indent(os, indent);
00260 }
00261 os << k << "->" << v;
00262 cnt++;
00263 }
00264 }
00265 os << " }" << endl;
00266 }
00267
00268 bool IntIntTblIter::Next( short& k, short& v) throw ()
00269 {
00270 bool res;
00271 assert(!(this->done));
00272 while (this->k < this->tbl->eltLen && this->tbl->elt[this->k] == Unused) {
00273 (this->k)++;
00274 }
00275 if (this->k < this->tbl->eltLen) {
00276 k = this->k;
00277 v = this->tbl->elt[k];
00278 (this->k)++;
00279 res = true;
00280 } else {
00281 this->done = true;
00282 res = false;
00283 }
00284 return res;
00285 }