00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "VestaLog.H"
00031 #include "VRConcurrency.H"
00032 #include "FP.H"
00033 #include "VMemPool.H"
00034 #include "VDirChangeable.H"
00035 #include "FPShortId.H"
00036 #include "Basics.H"
00037
00038 #include "math.h"
00039 #include <VestaConfig.H>
00040 #include <Thread.H>
00041
00042
00043 #define START_FPTBL_SIZE 5000
00044 #define MAX_FPTBL_SIZE 50000000
00045 #define RESIZE_TRIGGER 0.7
00046 #define RESIZE_FACTOR 2.0
00047
00048
00049
00050
00051 static Basics::mutex mu;
00052 static FPShortIdTable *fpFileSidTable;
00053 static FPShortIdTable *fpDirSidTable;
00054
00055
00056
00057
00058 FP::Tag
00059 DirFP(Bit8* rep)
00060 {
00061 VDirChangeable vdc(VestaSource::immutableDirectory, rep);
00062 return vdc.fptag();
00063 }
00064
00065 ShortId
00066 DirId(Bit8* rep) {
00067 VDirChangeable vdc(VestaSource::immutableDirectory, rep);
00068 return vdc.getID();
00069 }
00070
00071 void
00072 InitFPShortId()
00073 {
00074 fpFileSidTable =
00075 NEW_CONSTR(FPShortIdTable,
00076 (VDirChangeable::efptag,
00077 VDirChangeable::value,
00078 START_FPTBL_SIZE, RESIZE_FACTOR, RESIZE_TRIGGER));
00079 fpDirSidTable =
00080 NEW_CONSTR(FPShortIdTable,
00081 (DirFP, DirId,
00082 START_FPTBL_SIZE, RESIZE_FACTOR, RESIZE_TRIGGER));
00083 }
00084
00085 void
00086 SetFPFileShortId(Bit8 *entry)
00087 {
00088 mu.lock();
00089 assert(fpFileSidTable->Set(entry, true));
00090 mu.unlock();
00091 }
00092
00093 void
00094 SetFPDirShortId(Bit8 *rep)
00095 {
00096 mu.lock();
00097 assert(fpDirSidTable->Set(rep, true));
00098 mu.unlock();
00099 }
00100
00101 ShortId
00102 GetFPShortId(const FP::Tag& fptag)
00103 {
00104 mu.lock();
00105 ShortId sid;
00106 sid = fpFileSidTable->Get(fptag);
00107 if (sid == NullShortId) {
00108 sid = fpDirSidTable->Get(fptag);
00109 }
00110 mu.unlock();
00111
00112 return sid;
00113 }
00114
00115 void
00116 DeleteAllFPShortId()
00117 {
00118 mu.lock();
00119 fpFileSidTable->Clear();
00120 fpDirSidTable->Clear();
00121 mu.unlock();
00122 }
00123
00124
00125
00126 FPShortIdTable::FPShortIdTable(GetFP getfp, GetSid getsid,
00127 Bit32 sizeHint, double resizeF, double resizeT)
00128 {
00129 this->getfp = getfp;
00130 this->getsid = getsid;
00131 tableSize = sizeHint;
00132 resizeFactor = resizeF;
00133 resizeTrigger = resizeT;
00134 table = NEW_PTRFREE_ARRAY(Bit32, sizeHint);
00135 numEntries = 0;
00136 memset(table, 0, tableSize * sizeof(Bit32));
00137 }
00138
00139 FPShortIdTable::~FPShortIdTable()
00140 {
00141 delete table;
00142 tableSize = 0;
00143 }
00144
00145 Bit32 FPShortIdTable::Size()
00146 {
00147 return tableSize;
00148 }
00149
00150 Bit32 FPShortIdTable::Entries()
00151 {
00152 return numEntries;
00153 }
00154
00155 bool FPShortIdTable::Resize(Bit32 size)
00156 {
00157 Bit32 *oldTable = table;
00158 Bit32 oldTableSize = tableSize;
00159 bool ret = true;
00160 int i;
00161
00162 table = NEW_PTRFREE_ARRAY(Bit32, size);
00163 if (!table) return false;
00164 tableSize = size;
00165 numEntries = 0;
00166
00167 memset(table, 0, tableSize * sizeof(Bit32));
00168
00169 for (i = 0; i < oldTableSize; i++) {
00170 if (oldTable[i] != 0) {
00171 Bit8 *ptr = (Bit8*)VMemPool::lengthenPointer(oldTable[i]);
00172 ret = Set(ptr, false);
00173 assert(ret);
00174 }
00175 }
00176 delete [] oldTable;
00177
00178 return ret;
00179 }
00180
00181
00182
00183 ShortId FPShortIdTable::Get(const FP::Tag& fptag)
00184 {
00185 Bit32 i,j,k;
00186 FP::Tag efptag;
00187
00188 i = j = fptag.Hash() % tableSize;
00189
00190 if (table[i] == (Bit32)NULL) return NullShortId;
00191 Bit8 *ptr = (Bit8*)VMemPool::lengthenPointer(table[i]);
00192 efptag = getfp(ptr);
00193 i = (i + 1) % tableSize;
00194
00195
00196 while((!(fptag == efptag)) && i!=j)
00197 {
00198 if (table[i] == (Bit32)NULL) return NullShortId;
00199 ptr = (Bit8*)VMemPool::lengthenPointer(table[i]);
00200 efptag = getfp(ptr);
00201 i = (i + 1) % tableSize;
00202 }
00203
00204 if (i!=j) return getsid(ptr);
00205 else return NullShortId;
00206 }
00207
00208
00209 bool FPShortIdTable::Set(Bit8 *ptr, bool resize)
00210 {
00211 Bit32 i,j;
00212 FP::Tag fptag;
00213
00214 fptag = getfp(ptr);
00215
00216 if (resize && (double)numEntries/(double)tableSize > resizeTrigger)
00217 assert(Resize((Bit32)floor((double)tableSize*resizeFactor)));
00218
00219 i = j = fptag.Hash() % tableSize;
00220 while (table[i]) {
00221 if (i == j-1) return false;
00222 FP::Tag fptag2;
00223 fptag2 = getfp((Bit8*)VMemPool::lengthenPointer(table[i]));
00224 if (fptag == fptag2) break;
00225 i = (i+1) % tableSize;
00226 }
00227
00228 table[i] = VMemPool::shortenPointer(ptr);
00229
00230 numEntries++;
00231 return true;
00232 }
00233
00234
00235 void
00236 FPShortIdTable::Clear()
00237 {
00238 numEntries = 0;
00239 memset(table, 0, tableSize * sizeof(Bit32));
00240 }
00241