00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "TBasket.h"
00012 #include "TBufferFile.h"
00013 #include "TTree.h"
00014 #include "TBranch.h"
00015 #include "TFile.h"
00016 #include "TBufferFile.h"
00017 #include "TMath.h"
00018 #include "TTreeCache.h"
00019 #include "TTreeCacheUnzip.h"
00020
00021 extern "C" void R__zip (Int_t cxlevel, Int_t *nin, char *bufin, Int_t *lout, char *bufout, Int_t *nout);
00022 extern "C" void R__unzip(Int_t *nin, UChar_t *bufin, Int_t *lout, char *bufout, Int_t *nout);
00023 extern "C" int R__unzip_header(Int_t *nin, UChar_t *bufin, Int_t *lout);
00024
00025 const Int_t kMAXBUF = 0xFFFFFF;
00026 const UInt_t kDisplacementMask = 0xFF000000;
00027
00028
00029 ClassImp(TBasket)
00030
00031
00032
00033
00034
00035
00036
00037
00038 TBasket::TBasket() : fCompressedSize(0),fCompressedBuffer(0)
00039 {
00040
00041
00042 fDisplacement = 0;
00043 fEntryOffset = 0;
00044 fBufferRef = 0;
00045 fBuffer = 0;
00046 fHeaderOnly = kFALSE;
00047 fBufferSize = 0;
00048 fNevBufSize = 0;
00049 fNevBuf = 0;
00050 fLast = 0;
00051 fBranch = 0;
00052 }
00053
00054
00055 TBasket::TBasket(TDirectory *motherDir) : TKey(motherDir),fCompressedSize(0),fCompressedBuffer(0)
00056 {
00057
00058
00059 fDisplacement = 0;
00060 fEntryOffset = 0;
00061 fBufferRef = 0;
00062 fBuffer = 0;
00063 fHeaderOnly = kFALSE;
00064 fBufferSize = 0;
00065 fNevBufSize = 0;
00066 fNevBuf = 0;
00067 fLast = 0;
00068 fBranch = 0;
00069 }
00070
00071
00072 TBasket::TBasket(const char *name, const char *title, TBranch *branch) :
00073 TKey(branch->GetDirectory()),fCompressedSize(0),fCompressedBuffer(0)
00074 {
00075
00076
00077 SetName(name);
00078 SetTitle(title);
00079 fClassName = "TBasket";
00080 fBufferSize = branch->GetBasketSize();
00081 fNevBufSize = branch->GetEntryOffsetLen();
00082 fNevBuf = 0;
00083 fEntryOffset = 0;
00084 fDisplacement= 0;
00085 fBuffer = 0;
00086 fBufferRef = new TBufferFile(TBuffer::kWrite, fBufferSize);
00087 fVersion += 1000;
00088 if (branch->GetDirectory()) {
00089 TFile *file = branch->GetFile();
00090 fBufferRef->SetParent(file);
00091 }
00092 fHeaderOnly = kTRUE;
00093 fLast = 0;
00094
00095 Streamer(*fBufferRef);
00096 fKeylen = fBufferRef->Length();
00097 fObjlen = fBufferSize - fKeylen;
00098 fLast = fKeylen;
00099 fBuffer = 0;
00100 fBranch = branch;
00101 fHeaderOnly = kFALSE;
00102 if (fNevBufSize) {
00103 fEntryOffset = new Int_t[fNevBufSize];
00104 for (Int_t i=0;i<fNevBufSize;i++) fEntryOffset[i] = 0;
00105 }
00106 branch->GetTree()->IncrementTotalBuffers(fBufferSize);
00107 }
00108
00109
00110 TBasket::~TBasket()
00111 {
00112
00113
00114 if (fDisplacement) delete [] fDisplacement;
00115 if (fEntryOffset) delete [] fEntryOffset;
00116 if (fBuffer == fCompressedBuffer) fBuffer = 0;
00117 if (fCompressedBuffer) delete [] fCompressedBuffer;
00118 fDisplacement= 0;
00119 fEntryOffset = 0;
00120 fCompressedSize = 0;
00121 fCompressedBuffer = 0;
00122 }
00123
00124
00125 void TBasket::AdjustSize(Int_t newsize)
00126 {
00127
00128
00129 if (fBuffer == fBufferRef->Buffer()) {
00130 fBufferRef->Expand(newsize);
00131 fBuffer = fBufferRef->Buffer();
00132 } else {
00133 fBufferRef->Expand(newsize);
00134 }
00135 fBranch->GetTree()->IncrementTotalBuffers(newsize-fBufferSize);
00136 fBufferSize = newsize;
00137 }
00138
00139
00140 Long64_t TBasket::CopyTo(TFile *to)
00141 {
00142
00143
00144
00145
00146
00147 fBufferRef->SetWriteMode();
00148 Int_t nout = fNbytes - fKeylen;
00149 fBuffer = fBufferRef->Buffer();
00150 Create(nout, to);
00151 fBufferRef->SetBufferOffset(0);
00152 fHeaderOnly = kTRUE;
00153 Streamer(*fBufferRef);
00154 fHeaderOnly = kFALSE;
00155 Int_t nBytes = WriteFileKeepBuffer(to);
00156
00157 return nBytes>0 ? nBytes : -1;
00158 }
00159
00160
00161 void TBasket::DeleteEntryOffset()
00162 {
00163
00164
00165 if (fEntryOffset) delete [] fEntryOffset;
00166 fEntryOffset = 0;
00167 fNevBufSize = 0;
00168 }
00169
00170
00171
00172 Int_t TBasket::DropBuffers()
00173 {
00174
00175
00176 if (!fBuffer && !fBufferRef) return 0;
00177
00178 if (fDisplacement) delete [] fDisplacement;
00179 if (fEntryOffset) delete [] fEntryOffset;
00180 if (fBufferRef) delete fBufferRef;
00181 if (fCompressedBuffer) delete [] fCompressedBuffer;
00182 fBufferRef = 0;
00183 fBuffer = 0;
00184 fDisplacement= 0;
00185 fEntryOffset = 0;
00186 fCompressedSize = 0;
00187 fCompressedBuffer = 0;
00188 fBranch->GetTree()->IncrementTotalBuffers(-fBufferSize);
00189 return fBufferSize;
00190 }
00191
00192
00193 Int_t TBasket::GetEntryPointer(Int_t entry)
00194 {
00195
00196
00197 Int_t offset;
00198 if (fEntryOffset) offset = fEntryOffset[entry];
00199 else offset = fKeylen + entry*fNevBufSize;
00200 fBufferRef->SetBufferOffset(offset);
00201 return offset;
00202 }
00203
00204
00205 Int_t TBasket::LoadBasketBuffers(Long64_t pos, Int_t len, TFile *file)
00206 {
00207
00208
00209
00210
00211 if (fBufferRef) {
00212
00213 fBufferRef->SetReadMode();
00214 fBufferRef->Reset();
00215
00216
00217 if (fBufferRef->BufferSize() < len) {
00218 fBufferRef->SetWriteMode();
00219 fBufferRef->Expand(len);
00220 fBufferRef->SetReadMode();
00221 }
00222 } else {
00223 fBufferRef = new TBufferFile(TBuffer::kRead, len);
00224 }
00225 fBufferRef->SetParent(file);
00226 char *buffer = fBufferRef->Buffer();
00227 file->Seek(pos);
00228 if (file->ReadBuffer(buffer,len)) {
00229 return 1;
00230 }
00231
00232 fBufferRef->SetReadMode();
00233 fBufferRef->SetBufferOffset(0);
00234 Streamer(*fBufferRef);
00235
00236 return 0;
00237 }
00238
00239
00240 void TBasket::MoveEntries(Int_t dentries)
00241 {
00242
00243
00244
00245 Int_t i;
00246
00247 if (dentries >= fNevBuf) return;
00248 Int_t bufbegin;
00249 Int_t moved;
00250
00251 if (fEntryOffset) {
00252 bufbegin = fEntryOffset[dentries];
00253 moved = bufbegin-GetKeylen();
00254
00255
00256
00257
00258 if (!fDisplacement) {
00259 fDisplacement = new Int_t[fNevBufSize];
00260 }
00261 for (i = 0; i<(fNevBufSize-dentries); ++i) {
00262 fDisplacement[i] = fEntryOffset[i+dentries];
00263 fEntryOffset[i] = fEntryOffset[i+dentries] - moved;
00264 }
00265 for (i = fNevBufSize-dentries; i<fNevBufSize; ++i) {
00266 fDisplacement[i] = 0;
00267 fEntryOffset[i] = 0;
00268 }
00269
00270 } else {
00271
00272
00273
00274
00275 bufbegin = GetKeylen() + dentries*fNevBufSize;
00276 moved = bufbegin-GetKeylen();
00277 }
00278 TBuffer *buf = GetBufferRef();
00279 char *buffer = buf->Buffer();
00280 memmove(buffer+GetKeylen(),buffer+bufbegin,buf->Length()-bufbegin);
00281 buf->SetBufferOffset(buf->Length()-moved);
00282 fNevBuf -= dentries;
00283 }
00284
00285
00286 Int_t TBasket::ReadBasketBuffers(Long64_t pos, Int_t len, TFile *file)
00287 {
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 if(!fBranch->GetDirectory()) {
00304 return -1;
00305 }
00306 Int_t badread= 0;
00307
00308 TFileCacheRead *pf = file->GetCacheRead();
00309 char *buffer = 0;
00310 Bool_t free = kTRUE;
00311 Int_t res = -1;
00312
00313 if (pf) res = pf->GetUnzipBuffer(&buffer, pos, len, &free);
00314
00315 if (res >= 0) {
00316
00317
00318
00319 if (fBufferRef) {
00320 fBufferRef->SetBuffer(buffer, res, free);
00321 fBufferRef->SetReadMode();
00322 fBufferRef->Reset();
00323 } else {
00324 fBufferRef = new TBufferFile(TBuffer::kRead, res, buffer, free);
00325 }
00326 fBufferRef->SetParent(file);
00327
00328 Streamer(*fBufferRef);
00329
00330 if (IsZombie()) {
00331 badread = 1;
00332 return badread;
00333 }
00334
00335 Bool_t oldCase = fObjlen==fNbytes-fKeylen
00336 && GetBranch()->GetCompressionLevel()!=0
00337 && file->GetVersion()<=30401;
00338 if (fObjlen > fNbytes-fKeylen || oldCase) {
00339 if (TestBit(TBufferFile::kNotDecompressed) && (fNevBuf==1)) {
00340
00341
00342 fBuffer = fBufferRef->Buffer();
00343
00344
00345 fBufferRef->SetBufferOffset(fNbytes);
00346
00347
00348 fBufferRef->SetBit(TBufferFile::kNotDecompressed);
00349
00350
00351
00352 delete [] fEntryOffset; fEntryOffset = 0;
00353 delete [] fDisplacement; fDisplacement = 0;
00354
00355 fBranch->GetTree()->IncrementTotalBuffers(fBufferSize);
00356 return badread;
00357 }
00358 }
00359
00360 fBuffer = fBufferRef->Buffer();
00361 len = fObjlen+fKeylen;
00362 }
00363 else{
00364 if (fBufferRef) {
00365 fBufferRef->SetReadMode();
00366 if (fBufferRef->BufferSize() < len) {
00367 fBufferRef->Expand(len);
00368 }
00369 fBufferRef->Reset();
00370 } else {
00371 fBufferRef = new TBufferFile(TBuffer::kRead, len);
00372 }
00373 fBufferRef->SetParent(file);
00374
00375 buffer = fBufferRef->Buffer();
00376 if (file->ReadBuffer(buffer,pos,len)) {
00377 badread = 1;
00378 return badread;
00379 }
00380
00381 Streamer(*fBufferRef);
00382
00383 if (IsZombie()) {
00384 badread = 1;
00385 return badread;
00386 }
00387
00388 Bool_t oldCase = fObjlen==fNbytes-fKeylen
00389 && GetBranch()->GetCompressionLevel()!=0
00390 && file->GetVersion()<=30401;
00391 if (fObjlen > fNbytes-fKeylen || oldCase) {
00392 if (TestBit(TBufferFile::kNotDecompressed) && (fNevBuf==1)) {
00393
00394
00395 fBuffer = fBufferRef->Buffer();
00396
00397
00398 fBufferRef->SetBufferOffset(fNbytes);
00399
00400
00401 fBufferRef->SetBit(TBufferFile::kNotDecompressed);
00402
00403
00404
00405 delete [] fEntryOffset; fEntryOffset = 0;
00406 delete [] fDisplacement; fDisplacement = 0;
00407
00408 fBranch->GetTree()->IncrementTotalBuffers(fBufferSize);
00409 return badread;
00410 }
00411
00412 if ((fObjlen+fKeylen) > fCompressedSize) {
00413
00414 Int_t nin, nbuf;
00415 UChar_t *bufcur = (UChar_t *)&buffer[fKeylen];
00416 if (R__unzip_header(&nin, bufcur, &nbuf)!=0) {
00417 Error("ReadBasketBuffers", "Inconsistency found in header (nin=%d, nbuf=%d)", nin, nbuf);
00418 badread = 1;
00419 return badread;
00420 }
00421 if (fCompressedSize) delete [] fCompressedBuffer;
00422 fCompressedSize = fObjlen+fKeylen;
00423 fCompressedBuffer = new char[fCompressedSize];
00424 }
00425 fBuffer = fCompressedBuffer;
00426 memcpy(fBuffer,buffer,fKeylen);
00427 char *objbuf = fBuffer + fKeylen;
00428 UChar_t *bufcur = (UChar_t *)&buffer[fKeylen];
00429 Int_t nin, nout, nbuf;
00430 Int_t noutot = 0;
00431 while (1) {
00432 Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
00433 if (hc!=0) break;
00434 if (oldCase && (nin > fObjlen || nbuf > fObjlen)) {
00435
00436 delete [] fBuffer;
00437 fBuffer = fBufferRef->Buffer();
00438 goto AfterBuffer;
00439 }
00440 R__unzip(&nin, bufcur, &nbuf, objbuf, &nout);
00441 if (!nout) break;
00442 noutot += nout;
00443 if (noutot >= fObjlen) break;
00444 bufcur += nin;
00445 objbuf += nout;
00446 }
00447 if (noutot != fObjlen) {
00448 Error("ReadBasketBuffers", "fNbytes = %d, fKeylen = %d, fObjlen = %d, noutot = %d, nout=%d, nin=%d, nbuf=%d", fNbytes,fKeylen,fObjlen, noutot,nout,nin,nbuf);
00449 badread = 1;
00450 }
00451
00452 char *temp = fBufferRef->Buffer();
00453 Int_t templen = fBufferRef->BufferSize();
00454 fBufferRef->ResetBit(TBuffer::kIsOwner);
00455 fBufferRef->SetBuffer(fBuffer, fCompressedSize, kTRUE);
00456 fCompressedBuffer = temp;
00457 fCompressedSize = templen;
00458 len = fObjlen+fKeylen;
00459 } else {
00460 fBuffer = fBufferRef->Buffer();
00461 }
00462 }
00463 AfterBuffer:
00464
00465 fBranch->GetTree()->IncrementTotalBuffers(fBufferSize);
00466
00467
00468 if (badread || !fBranch->GetEntryOffsetLen()) {
00469 return badread;
00470 }
00471 delete [] fEntryOffset;
00472 fEntryOffset = 0;
00473 fBufferRef->SetBufferOffset(fLast);
00474 fBufferRef->ReadArray(fEntryOffset);
00475 if (!fEntryOffset) {
00476 fEntryOffset = new Int_t[fNevBuf+1];
00477 fEntryOffset[0] = fKeylen;
00478 Warning("ReadBasketBuffers","basket:%s has fNevBuf=%d but fEntryOffset=0, pos=%lld, len=%d, fNbytes=%d, fObjlen=%d, trying to repair",GetName(),fNevBuf,pos,len,fNbytes,fObjlen);
00479 return badread;
00480 }
00481 delete [] fDisplacement;
00482 fDisplacement = 0;
00483 if (fBufferRef->Length() != len) {
00484
00485
00486
00487
00488 fBufferRef->ReadArray(fDisplacement);
00489 }
00490
00491 return badread;
00492 }
00493
00494
00495 Int_t TBasket::ReadBasketBytes(Long64_t pos, TFile *file)
00496 {
00497
00498
00499
00500
00501
00502 const Int_t len = 128;
00503 char buffer[len];
00504 Int_t keylen;
00505 file->GetRecordHeader(buffer, pos,len, fNbytes, fObjlen, keylen);
00506 fKeylen = keylen;
00507 return fNbytes;
00508 }
00509
00510
00511 void TBasket::Reset()
00512 {
00513
00514
00515
00516
00517
00518
00519
00520 Int_t curSize = fBufferRef->BufferSize();
00521
00522 Int_t curLen = (GetObjlen() + GetKeylen());
00523 if (curSize > 2*curLen)
00524 {
00525 Int_t curBsize = fBranch->GetBasketSize();
00526 if (curSize > 2*curBsize ) {
00527 Int_t avgSize = (fBranch->GetTotBytes() / (1+fBranch->GetWriteBasket()));
00528 if (curSize > 2*avgSize) {
00529 Int_t newSize = curBsize;
00530 if (curLen > newSize) {
00531 newSize = curLen;
00532 }
00533 if (avgSize > newSize) {
00534 newSize = avgSize;
00535 }
00536 newSize = newSize + 512 - newSize%512;
00537 fBufferRef->Expand(newSize);
00538 }
00539 }
00540 }
00541
00542 TKey::Reset();
00543
00544 Int_t newNevBufSize = fBranch->GetEntryOffsetLen();
00545 if (newNevBufSize==0) {
00546 delete [] fEntryOffset;
00547 fEntryOffset = 0;
00548 } else if (newNevBufSize > fNevBufSize) {
00549 delete [] fEntryOffset;
00550 fEntryOffset = new Int_t[newNevBufSize];
00551 } else {
00552 if (!fEntryOffset) {
00553 fEntryOffset = new Int_t[newNevBufSize];
00554 }
00555 }
00556 fNevBufSize = newNevBufSize;
00557
00558 fNevBuf = 0;
00559 Int_t *storeEntryOffset = fEntryOffset;
00560 fEntryOffset = 0;
00561 Int_t *storeDisplacement = fDisplacement;
00562 fDisplacement= 0;
00563 fBuffer = 0;
00564
00565 fBufferRef->Reset();
00566 fBufferRef->SetWriteMode();
00567
00568 fHeaderOnly = kTRUE;
00569 fLast = 0;
00570
00571 Streamer(*fBufferRef);
00572
00573 fKeylen = fBufferRef->Length();
00574 fObjlen = fBufferSize - fKeylen;
00575 fLast = fKeylen;
00576 fBuffer = 0;
00577 fHeaderOnly = kFALSE;
00578 fDisplacement= storeDisplacement;
00579 fEntryOffset = storeEntryOffset;
00580 if (fNevBufSize) {
00581 for (Int_t i=0;i<fNevBufSize;i++) fEntryOffset[i] = 0;
00582 }
00583 }
00584
00585
00586 void TBasket::SetReadMode()
00587 {
00588
00589
00590 fLast = fBufferRef->Length();
00591 fBufferRef->SetReadMode();
00592 }
00593
00594
00595 void TBasket::SetWriteMode()
00596 {
00597
00598
00599 fBufferRef->SetWriteMode();
00600 fBufferRef->SetBufferOffset(fLast);
00601 }
00602
00603
00604 void TBasket::Streamer(TBuffer &b)
00605 {
00606
00607
00608 char flag;
00609 if (b.IsReading()) {
00610 TKey::Streamer(b);
00611 Version_t v = b.ReadVersion();
00612 b >> fBufferSize;
00613 b >> fNevBufSize;
00614 if (fNevBufSize < 0) {
00615 Error("Streamer","The value of fNevBufSize is incorrect (%d) ; trying to recover by setting it to zero",fNevBufSize);
00616 MakeZombie();
00617 fNevBufSize = 0;
00618 }
00619 b >> fNevBuf;
00620 b >> fLast;
00621 b >> flag;
00622 if (fLast > fBufferSize) fBufferSize = fLast;
00623 if (!flag) return;
00624 if (flag%10 != 2) {
00625 delete [] fEntryOffset;
00626 fEntryOffset = new Int_t[fNevBufSize];
00627 if (fNevBuf) b.ReadArray(fEntryOffset);
00628 if (20<flag && flag<40) {
00629 for(int i=0; i<fNevBuf; i++){
00630 fEntryOffset[i] &= ~kDisplacementMask;
00631 }
00632 }
00633 if (flag>40) {
00634 fDisplacement = new Int_t[fNevBufSize];
00635 b.ReadArray(fDisplacement);
00636 }
00637 }
00638 if (flag == 1 || flag > 10) {
00639 fBufferRef = new TBufferFile(TBuffer::kRead,fBufferSize);
00640 fBufferRef->SetParent(b.GetParent());
00641 char *buf = fBufferRef->Buffer();
00642 if (v > 1) b.ReadFastArray(buf,fLast);
00643 else b.ReadArray(buf);
00644 fBufferRef->SetBufferOffset(fLast);
00645
00646
00647
00648 }
00649 } else {
00650 TKey::Streamer(b);
00651 b.WriteVersion(TBasket::IsA());
00652 if (fBufferRef) {
00653 Int_t curLast = fBufferRef->Length();
00654 if (!fHeaderOnly && !fSeekKey && curLast > fLast) fLast = curLast;
00655 }
00656 if (fLast > fBufferSize) fBufferSize = fLast;
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 b << fBufferSize;
00690 b << fNevBufSize;
00691 b << fNevBuf;
00692 b << fLast;
00693 flag = 1;
00694 if (!fEntryOffset) flag = 2;
00695 if (fBufferRef) flag += 10;
00696 if (fDisplacement) flag += 40;
00697 if (fHeaderOnly) flag = 0;
00698 b << flag;
00699 if (fHeaderOnly) return;
00700 if (fEntryOffset && fNevBuf) {
00701 b.WriteArray(fEntryOffset, fNevBuf);
00702 if (fDisplacement) b.WriteArray(fDisplacement, fNevBuf);
00703 }
00704 if (fBufferRef) {
00705 char *buf = fBufferRef->Buffer();
00706 b.WriteFastArray(buf, fLast);
00707 }
00708 }
00709 }
00710
00711
00712 void TBasket::Update(Int_t offset, Int_t skipped)
00713 {
00714
00715
00716 if (fEntryOffset) {
00717 if (fNevBuf+1 >= fNevBufSize) {
00718 Int_t newsize = TMath::Max(10,2*fNevBufSize);
00719 Int_t *newoff = TStorage::ReAllocInt(fEntryOffset, newsize,
00720 fNevBufSize);
00721 if (fDisplacement) {
00722 Int_t *newdisp = TStorage::ReAllocInt(fDisplacement, newsize,
00723 fNevBufSize);
00724 fDisplacement = newdisp;
00725 }
00726 fEntryOffset = newoff;
00727 fNevBufSize = newsize;
00728
00729
00730 if (fBranch->GetWriteBasket() < 10) {
00731 fBranch->SetEntryOffsetLen(newsize);
00732 }
00733 }
00734 fEntryOffset[fNevBuf] = offset;
00735
00736 if (skipped!=offset && !fDisplacement){
00737 fDisplacement = new Int_t[fNevBufSize];
00738 for (Int_t i = 0; i<fNevBufSize; i++) fDisplacement[i] = fEntryOffset[i];
00739 }
00740 if (fDisplacement) {
00741 fDisplacement[fNevBuf] = skipped;
00742 fBufferRef->SetBufferDisplacement(skipped);
00743 }
00744 }
00745
00746 fNevBuf++;
00747 }
00748
00749
00750 Int_t TBasket::WriteBuffer()
00751 {
00752
00753
00754
00755
00756
00757
00758
00759 const Int_t kWrite = 1;
00760 TDirectory::TContext ctxt(0);
00761 TFile *file = fBranch->GetFile(kWrite);
00762 if (!file) return 0;
00763 if (!file->IsWritable()) {
00764 return -1;
00765 }
00766 fMotherDir = file;
00767
00768 if (fBufferRef->TestBit(TBufferFile::kNotDecompressed)) {
00769
00770 Bool_t writing = fBufferRef->IsWriting();
00771 fBufferRef->SetReadMode();
00772 fBufferRef->SetBufferOffset(0);
00773
00774 Streamer(*fBufferRef);
00775 if (writing) fBufferRef->SetWriteMode();
00776 Int_t nout = fNbytes - fKeylen;
00777
00778 fBuffer = fBufferRef->Buffer();
00779
00780 Create(nout,file);
00781 fBufferRef->SetBufferOffset(0);
00782 fHeaderOnly = kTRUE;
00783
00784 Streamer(*fBufferRef);
00785 int nBytes = WriteFileKeepBuffer();
00786 fHeaderOnly = kFALSE;
00787 return nBytes>0 ? fKeylen+nout : -1;
00788 }
00789
00790
00791
00792 fLast = fBufferRef->Length();
00793 if (fEntryOffset) {
00794 fBufferRef->WriteArray(fEntryOffset,fNevBuf+1);
00795 delete [] fEntryOffset; fEntryOffset = 0;
00796 if (fDisplacement) {
00797 fBufferRef->WriteArray(fDisplacement,fNevBuf+1);
00798 delete [] fDisplacement; fDisplacement = 0;
00799 }
00800 }
00801
00802 Int_t lbuf, nout, noutot, bufmax, nzip;
00803 lbuf = fBufferRef->Length();
00804 fObjlen = lbuf - fKeylen;
00805
00806 fHeaderOnly = kTRUE;
00807 fCycle = fBranch->GetWriteBasket();
00808 Int_t cxlevel = fBranch->GetCompressionLevel();
00809 if (cxlevel > 0) {
00810
00811 Int_t nbuffers = fObjlen/kMAXBUF;
00812 Int_t buflen = fKeylen + fObjlen + 28;
00813 if (buflen > fCompressedSize) {
00814 if (fCompressedSize) delete [] fCompressedBuffer;
00815 fCompressedSize = buflen;
00816 fCompressedBuffer = new char[fCompressedSize];
00817 }
00818 fBuffer = fCompressedBuffer;
00819 char *objbuf = fBufferRef->Buffer() + fKeylen;
00820 char *bufcur = &fBuffer[fKeylen];
00821 noutot = 0;
00822 nzip = 0;
00823 for (Int_t i=0;i<=nbuffers;i++) {
00824 if (i == nbuffers) bufmax = fObjlen -nzip;
00825 else bufmax = kMAXBUF;
00826
00827 R__zip(cxlevel, &bufmax, objbuf, &bufmax, bufcur, &nout);
00828
00829
00830
00831
00832 if (nout == 0 || nout >= fObjlen) {
00833 nout = fObjlen;
00834
00835
00836
00837 fBuffer = fBufferRef->Buffer();
00838 Create(fObjlen,file);
00839 fBufferRef->SetBufferOffset(0);
00840
00841 Streamer(*fBufferRef);
00842 if ((nout+fKeylen)>buflen) {
00843 Warning("WriteBuffer","Possible memory corruption due to compression algorithm, wrote %d bytes past the end of a block of %d bytes. fNbytes=%d, fObjLen=%d, fKeylen=%d",
00844 (nout+fKeylen-buflen),buflen,fNbytes,fObjlen,fKeylen);
00845 }
00846 goto WriteFile;
00847 }
00848 bufcur += nout;
00849 noutot += nout;
00850 objbuf += kMAXBUF;
00851 nzip += kMAXBUF;
00852 }
00853 nout = noutot;
00854 Create(noutot,file);
00855 fBufferRef->SetBufferOffset(0);
00856
00857 Streamer(*fBufferRef);
00858 memcpy(fBuffer,fBufferRef->Buffer(),fKeylen);
00859 } else {
00860 fBuffer = fBufferRef->Buffer();
00861 Create(fObjlen,file);
00862 fBufferRef->SetBufferOffset(0);
00863
00864 Streamer(*fBufferRef);
00865 nout = fObjlen;
00866 }
00867
00868 WriteFile:
00869 Int_t nBytes = WriteFileKeepBuffer();
00870 fHeaderOnly = kFALSE;
00871 return nBytes>0 ? fKeylen+nout : -1;
00872 }
00873