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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "TEntryListBlock.h"
00050 #include "TString.h"
00051
00052 ClassImp(TEntryListBlock)
00053
00054
00055 TEntryListBlock::TEntryListBlock()
00056 {
00057
00058
00059 fIndices = 0;
00060 fN = kBlockSize;
00061 fNPassed = 0;
00062 fType = -1;
00063 fPassing = 1;
00064 fCurrent = 0;
00065 fLastIndexReturned = -1;
00066 fLastIndexQueried = -1;
00067 }
00068
00069
00070 TEntryListBlock::TEntryListBlock(const TEntryListBlock &eblock) : TObject(eblock)
00071 {
00072
00073
00074 Int_t i;
00075 fN = eblock.fN;
00076 if (eblock.fIndices){
00077 fIndices = new UShort_t[fN];
00078 for (i=0; i<fN; i++)
00079 fIndices[i] = eblock.fIndices[i];
00080 } else {
00081 fIndices = 0;
00082 }
00083 fNPassed = eblock.fNPassed;
00084 fType = eblock.fType;
00085 fPassing = eblock.fPassing;
00086 fCurrent = eblock.fCurrent;
00087 fLastIndexReturned = -1;
00088 fLastIndexQueried = -1;
00089 }
00090
00091
00092
00093 TEntryListBlock::~TEntryListBlock()
00094 {
00095
00096
00097 if (fIndices)
00098 delete [] fIndices;
00099 fIndices = 0;
00100 }
00101
00102
00103 Bool_t TEntryListBlock::Enter(Int_t entry)
00104 {
00105
00106
00107
00108
00109 if (entry > kBlockSize*16) {
00110 Error("Enter", "illegal entry value!");
00111 return 0;
00112 }
00113 if (!fIndices){
00114 fIndices = new UShort_t[kBlockSize] ;
00115 for (Int_t i=0; i<kBlockSize; i++)
00116 fIndices[i] = 0;
00117 fType = 0;
00118 }
00119 if (fType==0){
00120
00121 Int_t i = entry>>4;
00122 Int_t j = entry & 15;
00123 if ((fIndices[i] & (1<<j))==0){
00124 fIndices[i] |= 1<<j;
00125 fNPassed++;
00126 return 1;
00127 } else {
00128 return 0;
00129 }
00130 }
00131
00132
00133 UShort_t *bits = new UShort_t[kBlockSize];
00134 Transform(1, bits);
00135 Enter(entry);
00136 return 0;
00137 }
00138
00139
00140 Bool_t TEntryListBlock::Remove(Int_t entry)
00141 {
00142
00143
00144
00145
00146
00147 if (entry > kBlockSize*16) {
00148 Error("Remove", "Illegal entry value!\n");
00149 return 0;
00150 }
00151 if (fType==0){
00152 Int_t i = entry>>4;
00153 Int_t j = entry & 15;
00154 if ((fIndices[i] & (1<<j))!=0){
00155 fIndices[i] &= (0xFFFF^(1<<j));
00156 fNPassed--;
00157 return 1;
00158 } else {
00159 return 0;
00160 }
00161 }
00162
00163
00164 UShort_t *bits = new UShort_t[kBlockSize];
00165 Transform(1, bits);
00166 return Remove(entry);
00167
00168 }
00169
00170 Int_t TEntryListBlock::Contains(Int_t entry)
00171 {
00172
00173
00174 if (entry > kBlockSize*16) {
00175 Error("Contains", "Illegal entry value!\n");
00176 return 0;
00177 }
00178 if (!fIndices && fPassing)
00179 return 0;
00180 if (fType==0 && fIndices){
00181
00182 Int_t i = entry>>4;
00183 Int_t j = entry & 15;
00184 Bool_t result = (fIndices[i] & (1<<j))!=0;
00185 return result;
00186 }
00187
00188 if (entry < fCurrent) fCurrent = 0;
00189 if (fPassing && fIndices){
00190 for (Int_t i = fCurrent; i<fNPassed; i++){
00191 if (fIndices[i]==entry){
00192 fCurrent = i;
00193 return kTRUE;
00194 }
00195 }
00196 } else {
00197 if (!fIndices || fNPassed==0){
00198
00199 return kTRUE;
00200 }
00201 if (entry > fIndices[fNPassed-1])
00202 return kTRUE;
00203 for (Int_t i= fCurrent; i<fNPassed; i++){
00204 if (fIndices[i]==entry){
00205 fCurrent = i;
00206 return kFALSE;
00207 }
00208 if (fIndices[i]>entry){
00209 fCurrent = i;
00210 return kTRUE;
00211 }
00212 }
00213 }
00214 return 0;
00215 }
00216
00217
00218 Int_t TEntryListBlock::Merge(TEntryListBlock *block)
00219 {
00220
00221
00222
00223 Int_t i, j;
00224 if (block->GetNPassed() == 0) return GetNPassed();
00225 if (GetNPassed() == 0){
00226
00227 fN = block->fN;
00228 fIndices = new UShort_t[fN];
00229 for (i=0; i<fN; i++)
00230 fIndices[i] = block->fIndices[i];
00231 fNPassed = block->fNPassed;
00232 fType = block->fType;
00233 fPassing = block->fPassing;
00234 fCurrent = block->fCurrent;
00235 fLastIndexReturned = -1;
00236 fLastIndexQueried = -1;
00237 return fNPassed;
00238 }
00239 if (fType==0){
00240
00241 if (block->fType == 0){
00242 for (i=0; i<kBlockSize*16; i++){
00243 if (block->Contains(i))
00244 Enter(i);
00245 }
00246 } else {
00247 if (block->fPassing){
00248
00249 for (i=0; i<block->fNPassed; i++){
00250 Enter(block->fIndices[i]);
00251 }
00252 } else {
00253
00254 if (block->fNPassed==0){
00255 for (i=0; i<kBlockSize*16; i++){
00256 Enter(i);
00257 }
00258 }
00259 for (j=0; j<block->fIndices[0]; j++)
00260 Enter(j);
00261 for (i=0; i<block->fNPassed-1; i++){
00262 for (j=block->fIndices[i]+1; j<block->fIndices[i+1]; j++){
00263 Enter(j);
00264 }
00265 }
00266 for (j=block->fIndices[block->fNPassed-1]+1; j<kBlockSize*16; j++)
00267 Enter(j);
00268 }
00269 }
00270 } else {
00271
00272 if (GetNPassed() + block->GetNPassed() > kBlockSize){
00273
00274 UShort_t *bits = new UShort_t[kBlockSize];
00275 Transform(1, bits);
00276 Merge(block);
00277 } else {
00278
00279 if (block->fType==1){
00280
00281
00282 Int_t en = block->fNPassed;
00283 Int_t newsize = fNPassed + en;
00284 UShort_t *newlist = new UShort_t[newsize];
00285 UShort_t *elst = block->fIndices;
00286 Int_t newpos, elpos;
00287 newpos = elpos = 0;
00288 for (i=0; i<fNPassed; i++) {
00289 while (elpos < en && fIndices[i] > elst[elpos]) {
00290 newlist[newpos] = elst[elpos];
00291 newpos++;
00292 elpos++;
00293 }
00294 if (fIndices[i] == elst[elpos]) elpos++;
00295 newlist[newpos] = fIndices[i];
00296 newpos++;
00297 }
00298 while (elpos < en) {
00299 newlist[newpos] = elst[elpos];
00300 newpos++;
00301 elpos++;
00302 }
00303 delete [] fIndices;
00304 fIndices = newlist;
00305 fNPassed = newpos;
00306 fN = fNPassed;
00307 } else {
00308
00309
00310 Int_t en = block->fNPassed;
00311 Int_t newsize = fNPassed + en;
00312 UShort_t *newlist = new UShort_t[newsize];
00313 Int_t newpos, current;
00314 newpos = current = 0;
00315 for (i=0; i<kBlockSize*16; i++){
00316 if (!block->Contains(i)) continue;
00317 while(current < fNPassed && fIndices[current]<i){
00318 newlist[newpos] = fIndices[current];
00319 current++;
00320 newpos++;
00321 }
00322 if (fIndices[current]==i) current++;
00323 newlist[newpos] = i;
00324 newpos++;
00325 }
00326 while(current<fNPassed){
00327 newlist[newpos] = fIndices[current];
00328 newpos++;
00329 current++;
00330 }
00331 delete [] fIndices;
00332 fIndices = newlist;
00333 fNPassed = newpos;
00334 fN = fNPassed;
00335 }
00336 }
00337 }
00338 fLastIndexQueried = -1;
00339 fLastIndexReturned = -1;
00340 OptimizeStorage();
00341 return GetNPassed();
00342 }
00343
00344
00345 Int_t TEntryListBlock::GetNPassed()
00346 {
00347
00348
00349
00350 if (fPassing)
00351 return fNPassed;
00352 else
00353 return kBlockSize*16-fNPassed;
00354 }
00355
00356
00357 Int_t TEntryListBlock::GetEntry(Int_t entry)
00358 {
00359
00360
00361
00362 if (entry > kBlockSize*16) return -1;
00363 if (entry > GetNPassed()) return -1;
00364 if (entry == fLastIndexQueried+1) return Next();
00365 else {
00366 Int_t i=0; Int_t j=0; Int_t entries_found=0;
00367 if (fType==0){
00368 if ((fIndices[i] & (1<<j))!=0)
00369 entries_found++;
00370 while (entries_found<entry+1){
00371 if (j==15){i++; j=0;}
00372 else j++;
00373 if ((fIndices[i] & (1<<j))!=0)
00374 entries_found++;
00375 }
00376 fLastIndexQueried = entry;
00377 fLastIndexReturned = i*16+j;
00378 return fLastIndexReturned;
00379 }
00380 if (fType==1){
00381 if (fPassing){
00382 fLastIndexQueried = entry;
00383 fLastIndexReturned = fIndices[entry];
00384 return fIndices[entry];
00385 } else {
00386 fLastIndexQueried = entry;
00387 if (!fIndices || fNPassed==0){
00388
00389 fLastIndexReturned = entry;
00390 return fLastIndexReturned;
00391 }
00392 for (i=0; i<fIndices[0]; i++){
00393 entries_found++;
00394 if (entries_found==entry+1){
00395 fLastIndexReturned = i;
00396 return fLastIndexReturned;
00397 }
00398 }
00399 for (i=0; i<fNPassed-1; i++){
00400 for (j=fIndices[i]+1; j<fIndices[i+1]; j++){
00401 entries_found++;
00402 if (entries_found==entry+1){
00403 fLastIndexReturned = j;
00404 return fLastIndexReturned;
00405 }
00406 }
00407 }
00408 for (j=fIndices[fNPassed-1]+1; j<kBlockSize*16; j++){
00409 entries_found++;
00410 if (entries_found==entry+1){
00411 fLastIndexReturned = j;
00412 return fLastIndexReturned;
00413 }
00414 }
00415 }
00416 }
00417 return -1;
00418 }
00419 }
00420
00421
00422 Int_t TEntryListBlock::Next()
00423 {
00424
00425
00426
00427 if (fLastIndexQueried==GetNPassed()-1){
00428 fLastIndexQueried=-1;
00429 fLastIndexReturned = -1;
00430 return -1;
00431 }
00432
00433 if (fType==0) {
00434
00435 Int_t i=0;
00436 Int_t j=0;
00437 fLastIndexReturned++;
00438 i = fLastIndexReturned>>4;
00439 j = fLastIndexReturned & 15;
00440 Bool_t result=(fIndices[i] & (1<<j))!=0;
00441 while (result==0){
00442 if (j==15) {j=0; i++;}
00443 else j++;
00444 result = (fIndices[i] & (1<<j))!=0;
00445 }
00446 fLastIndexReturned = i*16+j;
00447 fLastIndexQueried++;
00448 return fLastIndexReturned;
00449
00450 }
00451 if (fType==1) {
00452 fLastIndexQueried++;
00453 if (fPassing){
00454 fLastIndexReturned = fIndices[fLastIndexQueried];
00455 return fIndices[fLastIndexQueried];
00456 } else {
00457 fLastIndexReturned++;
00458 while (!Contains(fLastIndexReturned)){
00459 fLastIndexReturned++;
00460 }
00461 return fLastIndexReturned;
00462 }
00463
00464 }
00465 return -1;
00466 }
00467
00468
00469 void TEntryListBlock::Print(const Option_t *option) const
00470 {
00471
00472
00473 TString opt = option;
00474 opt.ToUpper();
00475 if (opt.Contains("A")) PrintWithShift(0);
00476 }
00477
00478
00479 void TEntryListBlock::PrintWithShift(Int_t shift) const
00480 {
00481
00482
00483
00484 Int_t i;
00485 if (fType==0){
00486 Int_t ibit, ibite;
00487 Bool_t result;
00488 for (i=0; i<kBlockSize*16; i++){
00489 ibite = i>>4;
00490 ibit = i & 15;
00491 result = (fIndices[ibite] & (1<<ibit))!=0;
00492 if (result)
00493 printf("%d\n", i+shift);
00494 }
00495 } else {
00496 if (fPassing){
00497 for (i=0; i<fNPassed; i++){
00498 printf("%d\n", fIndices[i]+shift);
00499 }
00500 } else {
00501 if (fNPassed==0){
00502 for (i=0; i<kBlockSize*16; i++)
00503 printf("%d\n", i+shift);
00504 return;
00505 }
00506 for (i=0; i<fIndices[0]; i++){
00507 printf("%d\n", i+shift);
00508 }
00509 for (i=0; i<fNPassed-1; i++){
00510 for (Int_t j=fIndices[i]+1; j<fIndices[i+1]; j++){
00511 printf("%d\n", j+shift);
00512 }
00513 }
00514 for (Int_t j=fIndices[fNPassed-1]+1; j<kBlockSize*16; j++){
00515 printf("%d\n", j+shift);
00516 }
00517 }
00518 }
00519 }
00520
00521
00522
00523 void TEntryListBlock::OptimizeStorage()
00524 {
00525
00526
00527 if (fType!=0) return;
00528 if (fNPassed > kBlockSize*15)
00529 fPassing = 0;
00530 if (fNPassed<kBlockSize || !fPassing){
00531
00532 UShort_t *indexnew = new UShort_t[fNPassed];
00533 Transform(0, indexnew);
00534 }
00535 }
00536
00537
00538
00539 void TEntryListBlock::Transform(Bool_t dir, UShort_t *indexnew)
00540 {
00541
00542
00543
00544
00545 Int_t i=0;
00546 Int_t ilist = 0;
00547 Int_t ibite, ibit;
00548 if (!dir) {
00549 for (i=0; i<kBlockSize*16; i++){
00550 ibite = i >> 4;
00551 ibit = i & 15;
00552 Bool_t result = (fIndices[ibite] & (1<<ibit))!=0;
00553 if (result && fPassing){
00554
00555 indexnew[ilist] = i;
00556 ilist++;
00557 }
00558 else if (!result && !fPassing){
00559
00560 indexnew[ilist] = i;
00561 ilist++;
00562 }
00563 }
00564 if (fIndices)
00565 delete [] fIndices;
00566 fIndices = indexnew;
00567 fType = 1;
00568 if (!fPassing)
00569 fNPassed = kBlockSize*16-fNPassed;
00570 fN = fNPassed;
00571 return;
00572 }
00573
00574
00575 if (fPassing){
00576 for (i=0; i<kBlockSize; i++)
00577 indexnew[i] = 0;
00578 for (i=0; i<fNPassed; i++){
00579 ibite = fIndices[i]>>4;
00580 ibit = fIndices[i] & 15;
00581 indexnew[ibite] |= 1<<ibit;
00582 }
00583 } else {
00584 for (i=0; i<kBlockSize; i++)
00585 indexnew[i] = 65535;
00586 for (i=0; i<fNPassed; i++){
00587 ibite = fIndices[i]>>4;
00588 ibit = fIndices[i] & 15;
00589 indexnew[ibite] ^= 1<<ibit;
00590 }
00591 fNPassed = kBlockSize*16-fNPassed;
00592 }
00593 if (fIndices)
00594 delete [] fIndices;
00595 fIndices = indexnew;
00596 fType = 0;
00597 fN = kBlockSize;
00598 fPassing = 1;
00599 return;
00600 }