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
00031
00032
00033 #ifndef _VDIRCH
00034 #define _VDIRCH 1
00035
00036 #include "VestaSource.H"
00037 #include "VDirVolatileRoot.H"
00038 #include "VMemPool.H"
00039 #include "AccessControl.H"
00040 #include "ShortIdRefCount.H"
00041 #include <assert.h>
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 #define VDIRCH_FLAGS 0
00107 #define VDIRCH_MOREORBASE 1
00108 #define VDIRCH_TIMESTAMP 5
00109 #define VDIRCH_ID 9
00110 #define VDIRCH_FPTAG 13
00111 #define VDIRCH_ENTRIES 29
00112 #define VDIRCH_ENDMARK 29 // if no entries
00113 #define VDIRCH_FREELEN 30 // if no entries
00114 #define VDIRCH_MINSIZE 34 // if no entries
00115 #define VDIRCH_EFLAGS 0
00116 #define VDIRCH_EVALUE 1
00117 #define VDIRCH_EATTRIB 5
00118
00119 #define VDIRCH_E1ARCLEN 9
00120 #define VDIRCH_E1ARC 10
00121 #define VDIRCH_E1MINSIZE 10 // if arcLen=0
00122
00123 #define VDIRCH_EFPTAG 9
00124 #define VDIRCH_E2ARCLEN 25
00125 #define VDIRCH_E2ARC 26
00126 #define VDIRCH_E2MINSIZE 26 // if arcLen=0
00127
00128 class VDirChangeable : public VestaSource {
00129 public:
00130
00131 void resync(AccessControl::Identity who =NULL) throw ();
00132 ShortId shortId() throw ();
00133 VestaSource::errorCode
00134 setTimestamp(time_t ts, AccessControl::Identity who =NULL) throw ();
00135 VestaSource::errorCode lookup(Arc arc, VestaSource*& result,
00136 AccessControl::Identity who =NULL,
00137 unsigned int indexOffset =0) throw();
00138 VestaSource::errorCode
00139 reallyDelete(Arc arc, AccessControl::Identity who =NULL,
00140 bool existCheck =true, time_t timestamp =0) throw();
00141 VestaSource::errorCode
00142 insertFile(Arc arc, ShortId sid, bool mast,
00143 AccessControl::Identity who =NULL,
00144 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00145 VestaSource** newvs =NULL, time_t timestamp =0,
00146 FP::Tag* fptag =NULL) throw();
00147 VestaSource::errorCode
00148 insertMutableFile(Arc arc, ShortId sid, bool mast,
00149 AccessControl::Identity who =NULL,
00150 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00151 VestaSource** newvs =NULL, time_t timestamp =0) throw();
00152 VestaSource::errorCode
00153 insertImmutableDirectory(Arc arc, VestaSource* dir, bool mast,
00154 AccessControl::Identity who =NULL,
00155 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00156 VestaSource** newvs =NULL, time_t timestamp =0,
00157 FP::Tag* fptag =NULL) throw();
00158 VestaSource::errorCode
00159 insertAppendableDirectory(Arc arc, bool mast,
00160 AccessControl::Identity who =NULL,
00161 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00162 VestaSource** newvs =NULL, time_t timestamp =0) throw();
00163 VestaSource::errorCode
00164 insertMutableDirectory(Arc arc, VestaSource* dir, bool mast,
00165 AccessControl::Identity who =NULL,
00166 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00167 VestaSource** newvs =NULL, time_t timestamp =0) throw();
00168 VestaSource::errorCode
00169 insertGhost(Arc arc, bool mast,
00170 AccessControl::Identity who =NULL,
00171 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00172 VestaSource** newvs =NULL, time_t timestamp =0) throw();
00173 VestaSource::errorCode
00174 insertStub(Arc arc, bool mast,
00175 AccessControl::Identity who =NULL,
00176 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00177 VestaSource** newvs =NULL, time_t timestamp =0) throw();
00178 VestaSource::errorCode
00179 renameTo(Arc arc, VestaSource* fromDir, Arc fromArc,
00180 AccessControl::Identity who =NULL,
00181 VestaSource::dupeCheck chk =VestaSource::dontReplace,
00182 time_t timestamp =0) throw();
00183 VestaSource::errorCode
00184 getBase(VestaSource*& result, AccessControl::Identity who =NULL) throw();
00185 VestaSource::errorCode
00186 list(unsigned int firstIndex,
00187 VestaSource::listCallback callback, void* closure,
00188 AccessControl::Identity who =NULL,
00189 bool deltaOnly =false, unsigned int indexOffset =0) throw();
00190
00191 VestaSource::errorCode
00192 lookupIndex(unsigned int index, VestaSource*& result,
00193 char* arcbuf =NULL) throw();
00194
00195
00196
00197
00198
00199
00200
00201
00202 VestaSource::errorCode
00203 makeIndexMutable(unsigned int index, VestaSource*& result,
00204 ShortId sid =NullShortId,
00205 Basics::uint64 copyMax = (Basics::uint64) -1,
00206 AccessControl::Identity who =NULL) throw();
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 void makeIndexImmutable(unsigned int index,
00217 const FP::Tag* fptag =NULL,
00218 ShortId newsid =NullShortId) throw();
00219
00220
00221
00222
00223
00224
00225 inline int getRefCount(ShortId sid, int default_count = 0)
00226 { return (sidref
00227 ? sidref->GetCount(sid, default_count)
00228 : default_count); }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 VestaSource::errorCode
00240 copyIndexToMutable(unsigned int index, VestaSource*& result,
00241 AccessControl::Identity who =NULL) throw();
00242
00243
00244
00245 errorCode setIndexMaster(unsigned int index, bool state,
00246 AccessControl::Identity who =NULL) throw();
00247
00248
00249
00250
00251
00252 void mark(bool byName =true, ArcTable* hidden =NULL) throw();
00253 static void markCallback(void* closure, VMemPool::typeCode type) throw();
00254 static bool sweepCallback(void* closure, VMemPool::typeCode type,
00255 void* addr, Bit32& size) throw();
00256 static void rebuildCallback(void* closure, VMemPool::typeCode type,
00257 void* addr, Bit32& size) throw();
00258
00259
00260 Bit32 checkpoint(Bit32& nextSP, std::fstream& ckpt) throw();
00261
00262
00263 void freeTree() throw();
00264
00265 errorCode
00266 measureDirectory(directoryStats &result,
00267 AccessControl::Identity who =NULL)
00268 throw (SRPC::failure);
00269
00270 errorCode
00271 collapseBase(AccessControl::Identity who =NULL)
00272 throw (SRPC::failure);
00273
00274
00275 enum { defaultRepSize = 512 };
00276 VDirChangeable(VestaSource::typeTag type,
00277 int size =defaultRepSize,
00278 ShortIdRefCount* sidref =NULL)
00279 throw();
00280
00281 VDirChangeable(VestaSource::typeTag type, Bit8* existingRep,
00282 ShortIdRefCount* sidref =NULL) throw();
00283
00284
00285
00286 void buildMutableSidref() throw();
00287
00288
00289
00290
00291
00292
00293 void checkMutableSidref(bool correct = false) throw();
00294
00295
00296 static void printStats() throw ();
00297
00298 virtual VestaSource *copy() throw();
00299
00300 private:
00301
00302 Bit8* repEndCache;
00303 unsigned int nextRawIndexCache;
00304 Bit8* baseCache;
00305 Bit8* lastRepBlockCache;
00306 int totalRepSizeCache;
00307
00308
00309
00310
00311
00312
00313
00314 public:
00315 inline bool hasName() throw() { return (bool) (rep[VDIRCH_FLAGS] & 1); };
00316 inline void setHasName(bool newval) throw()
00317 { rep[VDIRCH_FLAGS] = (rep[VDIRCH_FLAGS] & 0xfe) | (int) newval; };
00318 inline bool visited() throw()
00319 { return (bool) ((rep[VDIRCH_FLAGS] & 2) != 0); };
00320 inline void setVisited(bool newval) throw()
00321 { rep[VDIRCH_FLAGS] =
00322 (rep[VDIRCH_FLAGS] & 0xfd) | ((int)newval << 1); };
00323 private:
00324 inline bool hasName(Bit8* repb) throw()
00325 { return (bool) (repb[VDIRCH_FLAGS] & 1); };
00326 inline void setHasName(Bit8* repb, bool newval) throw()
00327 { repb[VDIRCH_FLAGS] = (repb[VDIRCH_FLAGS] & 0xfe) | (int) newval; };
00328 inline bool visited(Bit8* repb) throw()
00329 { return (bool) ((repb[VDIRCH_FLAGS] & 2) != 0); };
00330 inline void setVisited(Bit8* repb, bool newval) throw()
00331 { repb[VDIRCH_FLAGS] =
00332 (repb[VDIRCH_FLAGS] & 0xfd) | ((int)newval << 1); };
00333
00334 enum { isNeither = 0, isMore = 1, isBase = 2 };
00335 static inline int isMoreOrBase(Bit8 *repb) throw()
00336 { return (repb[VDIRCH_FLAGS] >> 2) & 3; };
00337 static inline void setIsMoreOrBase(Bit8* repb, int newval) throw()
00338 { repb[VDIRCH_FLAGS] = (repb[VDIRCH_FLAGS] & 0xf3) | (newval << 2); };
00339 static inline Bit32 moreOrBase(Bit8 *repb) throw()
00340 { Bit32 val; memcpy(&val, &repb[VDIRCH_MOREORBASE], 4); return val; };
00341 static inline void setMoreOrBase(Bit8 *repb, Bit32 newval) throw()
00342 { memcpy(&repb[VDIRCH_MOREORBASE], &newval, 4); };
00343 public:
00344 inline time_t timestamp() throw()
00345 { Bit32 val; memcpy(&val, &rep[VDIRCH_TIMESTAMP], 4);
00346 return (time_t) val; };
00347 private:
00348 inline void setTimestampField(Bit32 newval) throw()
00349 { memcpy(&rep[VDIRCH_TIMESTAMP], &newval, 4); };
00350
00351 inline Bit32 getID() throw()
00352 { Bit32 val; memcpy(&val, &rep[VDIRCH_ID], 4); return val; };
00353 inline void setID(Bit32 newval) throw()
00354 { memcpy(&rep[VDIRCH_ID], &newval, 4); };
00355
00356
00357 inline FP::Tag fptag() throw()
00358 { FP::Tag ret;
00359 memcpy(ret.Words(), &rep[VDIRCH_FPTAG], FP::ByteCnt); return ret; };
00360 inline void setFPTag(const FP::Tag& newfptag) throw()
00361 { memcpy(&rep[VDIRCH_FPTAG], ((FP::Tag&)newfptag).Words(),
00362 FP::ByteCnt); };
00363 inline Bit32 snapshot() throw()
00364 { Bit32 val; memcpy(&val, &rep[VDIRCH_FPTAG], 4); return val; };
00365 inline void setSnapshot(Bit32 newval) throw()
00366 { memcpy(&rep[VDIRCH_FPTAG], &newval, 4); };
00367
00368 inline Bit8* firstEntry(Bit8 *repb) throw()
00369 { return &repb[VDIRCH_ENTRIES]; };
00370 static inline Bit8* nextEntry(Bit8* entry) throw() {
00371 if (hasEFPTag(entry))
00372 return entry + entry[VDIRCH_E2ARCLEN] + VDIRCH_E2MINSIZE;
00373 else
00374 return entry + entry[VDIRCH_E1ARCLEN] + VDIRCH_E1MINSIZE;
00375 };
00376
00377 static inline bool isEndMark(Bit8* entry) throw()
00378 { return (bool) (entry[VDIRCH_EFLAGS] == 0xff); };
00379 static inline bool masterFlag(Bit8* entry) throw()
00380 { return (bool) (entry[VDIRCH_EFLAGS] & 1); };
00381 static inline void setMasterFlag(Bit8* entry, bool newval) throw()
00382 { entry[VDIRCH_EFLAGS] = (entry[VDIRCH_EFLAGS] & 0xfe) | (int) newval; };
00383 static inline bool inUse(Bit8* entry) throw()
00384 { return (bool) ((entry[VDIRCH_EFLAGS] & 2) != 0); };
00385 static inline void setInUse(Bit8* entry, bool newval) throw()
00386 { entry[VDIRCH_EFLAGS] =
00387 (entry[VDIRCH_EFLAGS] & 0xfd) | ((int) newval << 1); };
00388 static inline bool hasEFPTag(Bit8* entry) throw()
00389 { return (bool) ((entry[VDIRCH_EFLAGS] & 4) != 0); };
00390 static inline void setHasEFPTag(Bit8* entry, bool newval) throw()
00391 { entry[VDIRCH_EFLAGS] =
00392 (entry[VDIRCH_EFLAGS] & 0xfb) | ((int) newval << 2); };
00393 static inline bool sameAsBase(Bit8* entry) throw()
00394 { return (bool) ((entry[VDIRCH_EFLAGS] & 8) != 0); };
00395 static inline void setSameAsBase(Bit8* entry, bool newval) throw()
00396 { entry[VDIRCH_EFLAGS] =
00397 (entry[VDIRCH_EFLAGS] & 0xf7) | ((int) newval << 3); };
00398 static inline VestaSource::typeTag type(Bit8* entry) throw()
00399 { return (VestaSource::typeTag) ((entry[VDIRCH_EFLAGS] >> 4) & 0xf); };
00400 static inline void setType(Bit8* entry, VestaSource::typeTag type) throw()
00401 { entry[VDIRCH_EFLAGS] =
00402 (entry[VDIRCH_EFLAGS] & 0x0f) | (((int) type) << 4); };
00403 static inline Bit32 value(Bit8* entry) throw()
00404 { Bit32 val; memcpy(&val, &entry[VDIRCH_EVALUE], 4); return val; };
00405 static inline void setValue(Bit8* entry, Bit32 value) throw()
00406 { memcpy(&entry[VDIRCH_EVALUE], &value, 4); };
00407 static inline Bit32 attrib(Bit8* entry) throw()
00408 { Bit32 val; memcpy(&val, &entry[VDIRCH_EATTRIB], 4); return val; };
00409 static inline void setAttrib(Bit8* entry, Bit32 attrib) throw()
00410 { memcpy(&entry[VDIRCH_EATTRIB], &attrib, 4); };
00411 inline Bit8* attribAddr(Bit8* entry) throw()
00412 { if (VestaSource::type == VestaSource::appendableDirectory ||
00413 VestaSource::type == VestaSource::mutableDirectory)
00414 return entry + VDIRCH_EATTRIB; else return NULL; };
00415 static inline FP::Tag efptag(Bit8* entry) throw()
00416 { FP::Tag ret; assert(hasEFPTag(entry));
00417 memcpy(ret.Words(), &entry[VDIRCH_EFPTAG], FP::ByteCnt); return ret; };
00418 static inline void setEFPTag(Bit8* entry, const FP::Tag& newfptag) throw()
00419 { assert(hasEFPTag(entry));
00420 memcpy(&entry[VDIRCH_EFPTAG], ((FP::Tag&)newfptag).Words(),
00421 FP::ByteCnt); };
00422 static inline int arcLen(Bit8* entry) throw()
00423 { return (int) entry[hasEFPTag(entry) ?
00424 VDIRCH_E2ARCLEN : VDIRCH_E1ARCLEN]; };
00425 static inline char* arc(Bit8* entry) throw()
00426 { return (char*) &entry[hasEFPTag(entry) ?
00427 VDIRCH_E2ARC : VDIRCH_E1ARC]; };
00428
00429 void fillCaches() throw();
00430 inline Bit8* repEnd() throw()
00431 { if (!repEndCache) fillCaches(); return repEndCache; };
00432 inline unsigned int nextRawIndex() throw()
00433 { if (!repEndCache) fillCaches(); return nextRawIndexCache; };
00434 inline Bit8* base() throw()
00435 { if (!repEndCache) fillCaches(); return baseCache; };
00436 inline Bit8* lastRepBlock() throw()
00437 { if (!repEndCache) fillCaches(); return lastRepBlockCache; };
00438 inline int totalRepSize() throw()
00439 { if (!repEndCache) fillCaches(); return totalRepSizeCache; };
00440 inline Bit32 freeLen() throw()
00441 { Bit32 val; memcpy(&val, repEnd() + 1, 4); return val; };
00442 inline void setFreeLen(Bit32 newval) throw()
00443 { memcpy(repEnd() + 1, &newval, 4); };
00444
00445
00446
00447
00448
00449
00450
00451
00452 Bit8* findArc(const char* arc, unsigned int& rawIndex,
00453 bool includeDeleted =false,
00454 bool includeOutdated =false) throw();
00455
00456
00457
00458
00459 Bit8* findRawIndex(unsigned int rawIndex, Bit8*& repBlock) throw();
00460
00461
00462
00463
00464
00465 Bit8* appendEntry(bool mast, bool sameAsBase,
00466 VestaSource::typeTag type, Bit32 value,
00467 Bit32 attrib, const FP::Tag* efptag,
00468 const char* arc, int arcLen) throw();
00469
00470
00471
00472
00473 static void setEntry(Bit8* entry, bool mast, bool sameAsBase,
00474 VestaSource::typeTag type, Bit32 value,
00475 Bit32 attrib, const FP::Tag* efptag) throw();
00476
00477
00478
00479
00480
00481 VestaSource::errorCode insertCommon(Arc arc, bool mast,
00482 VestaSource::typeTag newtype,
00483 AccessControl::Identity who,
00484 VestaSource::dupeCheck chk,
00485 const char** setOwner, ShortId* delsid,
00486 Bit32* attribs = NULL) throw();
00487
00488
00489
00490 VDirChangeable* copyMutableToImmutable(const FP::Tag& fptag) throw();
00491
00492 VDirChangeable* collapse(unsigned int newSize = defaultRepSize) throw();
00493
00494
00495
00496 ShortIdRefCount* sidref;
00497
00498
00499
00500 ShortIdRefCount *rebuildMutableSidref() throw();
00501
00502
00503 friend bool filterListCallback(void* closure, typeTag type,
00504 Arc arc, unsigned int index,
00505 unsigned int pseudoInode,
00506 bool mast) throw();
00507 friend VestaSource::errorCode
00508 VDirVolatileRoot::createVolatileDirectory(char* hostname, char* port,
00509 Bit64 handle,
00510 VestaSource*& result,
00511 time_t timestamp,
00512 LongId::lockKindTag lockKind,
00513 ReadersWritersLock** lock,
00514 bool readOnlyExisting)
00515 throw();
00516 friend VestaSource::errorCode
00517 VDirVolatileRoot::lookupIndexAndLock(unsigned int index,
00518 VestaSource*& result,
00519 LongId::lockKindTag lockKind,
00520 ReadersWritersLock** lock)
00521 throw();
00522 friend VestaSource*
00523 VDCLookupResult(VDirChangeable* dir, Bit8* entry, unsigned int index);
00524
00525 friend VestaSource*
00526 LongId::lookup(LongId::lockKindTag lockKind, ReadersWritersLock** lock)
00527 throw (SRPC::failure);
00528
00529 friend FP::Tag DirFP(Bit8* rep);
00530 friend ShortId DirId(Bit8* rep);
00531 friend void InitFPShortId();
00532 };
00533
00534
00535 #endif