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 #include <FP.H>
00028 #include <BitVector.H>
00029
00030 #include "IntIntTblLR.H"
00031 #include "Combine.H"
00032
00033 using std::ostream;
00034 using std::istream;
00035 using std::endl;
00036
00037
00038
00039 static Combine::XorTag& NamesXOR(const FP::List& fps, const BitVector& bv,
00040 Combine::XorTag& res, const IntIntTblLR *imap = NULL) throw ()
00041
00042
00043
00044
00045 {
00046 int i;
00047 FP::Tag *fp;
00048
00049
00050 res.w = 0UL;
00051
00052 if (bv.Size() > 0) {
00053
00054 BVIter iter(bv);
00055 while (iter.Next( i)) {
00056 short mapRes;
00057 if (imap == (IntIntTblLR *)NULL)
00058 mapRes = i;
00059 else {
00060 bool inMap = imap->Get(i, mapRes);
00061 assert(inMap);
00062 }
00063 res ^= fps.fp[mapRes];
00064 }
00065 }
00066 return res;
00067 }
00068
00069 Combine::XorTag::XorTag(const FP::List& pkFPs, BitVector& bv,
00070 const IntIntTblLR *imap) throw ()
00071 {
00072 (void)NamesXOR(pkFPs, bv, *this, imap);
00073 }
00074
00075 void Combine::XorTag::Debug(ostream &os) const throw ()
00076 {
00077 char buff[17];
00078 int printLen = sprintf(buff, "%016" FORMAT_LENGTH_INT_64 "x", this->w);
00079 assert(printLen == 16);
00080 os << buff;
00081 }
00082
00083
00084
00085 struct AvailBuff {
00086 char *buff;
00087 int len;
00088 AvailBuff *next;
00089 };
00090
00091 static Basics::mutex availMu;
00092 static AvailBuff *head;
00093
00094 static AvailBuff *NextAvail(int size) throw ()
00095
00096 {
00097 AvailBuff *res;
00098 availMu.lock();
00099 if (head == (AvailBuff *)NULL) {
00100 res = NEW(AvailBuff);
00101 res->buff = NEW_PTRFREE_ARRAY(char, size);
00102 res->len = size;
00103 availMu.unlock();
00104 } else {
00105 res = head;
00106 head = head->next;
00107 availMu.unlock();
00108 if (res->len < size) {
00109 delete[] res->buff;
00110 res->buff = NEW_PTRFREE_ARRAY(char, size);
00111 }
00112 }
00113 return res;
00114 }
00115
00116 static void ReturnAvail(AvailBuff *avail) throw ()
00117
00118 {
00119 availMu.lock();
00120 avail->next = head;
00121 head = avail;
00122 availMu.unlock();
00123 }
00124
00125 static FP::Tag& NamesFP(const FP::List& fps, const BitVector& bv,
00126 FP::Tag& res, const IntIntTblLR *imap = NULL) throw ()
00127
00128
00129
00130
00131
00132 {
00133 AvailBuff *avail = (AvailBuff *)NULL;
00134 char *fpBuff;
00135 int buffLen = 0;
00136
00137 if (bv.Size() > 0) {
00138
00139 int i;
00140 BVIter iter(bv);
00141
00142 avail = NextAvail(bv.Size() * FP::ByteCnt);
00143 fpBuff = avail->buff;
00144 while (iter.Next( i)) {
00145 short mapRes;
00146 if (imap == (IntIntTblLR *)NULL)
00147 mapRes = i;
00148 else {
00149 bool inMap = imap->Get(i, mapRes);
00150 assert(inMap);
00151 }
00152 Word *words = fps.fp[mapRes].Words();
00153 memcpy(fpBuff + buffLen, (char *)words, FP::ByteCnt);
00154 buffLen += FP::ByteCnt;
00155 }
00156 }
00157
00158
00159 res = FP::Tag(fpBuff, buffLen);
00160
00161
00162 if (avail != (AvailBuff *)NULL) ReturnAvail(avail);
00163 return res;
00164 }
00165
00166 Combine::FPTag::FPTag(const FP::List& fps, const BitVector& bv,
00167 const IntIntTblLR *imap) throw ()
00168 {
00169 (void)NamesFP(fps, bv, *this, imap);
00170 }
00171
00172
00173
00174 void Combine::XorFPTag::Init(const FP::List& fps, const BitVector& bv,
00175 const IntIntTblLR *imap) throw ()
00176 {
00177 (void)NamesXOR(fps, bv, this->xort, imap);
00178 this->xort.w &= ~LSB;
00179 }
00180
00181 FP::Tag& Combine::XorFPTag::FPVal(const FP::List &fps,
00182 const BitVector &bv, const IntIntTblLR *imap) throw ()
00183 {
00184 if (!(this->xort.w & LSB)) {
00185 (void)NamesFP(fps, bv, this->fp, imap);
00186 this->xort.w |= LSB;
00187 }
00188 return this->fp;
00189 }
00190
00191 void Combine::XorFPTag::Log(VestaLog &log) const
00192 throw (VestaLog::Error)
00193 {
00194 xort.Log(log);
00195 if (this->xort.w & LSB) fp.Log(log);
00196 }
00197
00198 void Combine::XorFPTag::Recover(RecoveryReader &rd)
00199 throw (VestaLog::Error, VestaLog::Eof)
00200 {
00201 this->xort.Recover(rd);
00202 if (this->xort.w & LSB) this->fp.Recover(rd);
00203 }
00204
00205 void Combine::XorFPTag::Write(ostream &ofs) const
00206 throw (FS::Failure)
00207 {
00208 this->xort.Write(ofs);
00209 if (this->xort.w & LSB) this->fp.Write(ofs);
00210 }
00211
00212 void Combine::XorFPTag::Read(istream &ifs)
00213 throw (FS::EndOfFile, FS::Failure)
00214 {
00215 this->xort.Read(ifs);
00216 if (this->xort.w & LSB) this->fp.Read(ifs);
00217 }
00218
00219 inline void Indent(ostream &os, int indent) throw ()
00220 {
00221 for (int i = 0; i < indent; i++) os << " ";
00222 }
00223
00224 void Combine::XorFPTag::Debug(ostream &os, int indent) const throw ()
00225 {
00226 Indent(os, indent); os << "xor = "; this->xort.Debug(os); os << endl;
00227 Indent(os, indent); os << "fp = ";
00228 if (this->xort.w & LSB) os << this->fp; else os << "<lazy>";
00229 }