14 #include "TTableSorter.h"
17 #include "TDataMember.h"
18 #include "TDataType.h"
19 #include "TMemberInspector.h"
21 typedef Int_t (*CALLQSORT) (
const void *,
const void *);
86 TTableSorter::TTableSorter() : fsimpleArray(0),fParentTable(0)
94 fColType = TTable::kNAN;
117 TTableSorter::TTableSorter(
const TTable &table, TString &colName,Int_t firstRow
118 ,Int_t numberRows):fsimpleArray(0),fParentTable(&table)
138 TTableSorter::TTableSorter(
const TTable *table, TString &colName,Int_t firstRow
139 ,Int_t numberRows):fsimpleArray(0),fParentTable(table)
165 TTableSorter::TTableSorter(
const TTable &table, SEARCHMETHOD search,
166 COMPAREMETHOD compare, Int_t firstRow,Int_t numberRows)
167 :fsimpleArray(0),fParentTable(&table)
169 fCompareMethod = compare;
171 TString colName =
"user's defined";
193 TTableSorter::TTableSorter(
const TTable *table, SEARCHMETHOD search,
194 COMPAREMETHOD compare, Int_t firstRow,Int_t numberRows)
195 :fsimpleArray(0),fParentTable(table)
197 fCompareMethod = compare;
199 TString colName =
"user's defined";
217 assert(fParentTable!=0);
221 fColType = TTable::kNAN;
230 TString n = fParentTable->GetName();
235 Char_t *name = (Char_t *) colName.Data();
236 if (!(name || strlen(colName.Data()))) { MakeZombie();
delete [] name;
return; }
237 name = StrDup(colName.Data());
240 if (firstRow > fParentTable->
GetNRows()) { MakeZombie();
delete [] name;
return; }
241 fFirstRow = firstRow;
243 fNumberOfRows = fParentTable->
GetNRows()- fFirstRow;
244 if (numberRows > 0) fNumberOfRows = TMath::Min(numberRows,fNumberOfRows);
246 fFirstParentRow= (
const char *)fParentTable->GetArray();
249 if (fNumberOfRows <=0 ) { MakeZombie();
delete [] name;
return; }
250 fSortIndex =
new void*[fNumberOfRows];
254 Char_t *br = name - 1;
255 while((br = strchr(br+1,
'['))) {
256 if (!fColDimensions) *br = 0;
265 if (fColDimensions) {
266 fIndexArray =
new Int_t[fColDimensions];
267 memset(fIndexArray,0,fColDimensions*
sizeof(Int_t));
269 const char *openBracket = colName.Data()-1;
270 const char *closeBracket = colName.Data()-1;
271 for (Int_t i=0; i< fColDimensions; i++) {
272 openBracket = strchr(openBracket+1,
'[');
273 closeBracket = strchr(closeBracket+1,
']');
274 if (closeBracket > openBracket)
275 fIndexArray[i] = atoi(openBracket+1);
277 Error(
"TTable ctor",
"Wrong parethethis <%s>",colName.Data());
283 if (colName !=
"user's defined") {
300 TTableSorter::TTableSorter(
const Float_t *simpleArray, Int_t arraySize, Int_t firstRow
302 :fsimpleArray((const Char_t*)simpleArray)
308 if (!fsimpleArray) { MakeZombie();
return; }
313 fColType = TTable::kFloat;
314 fColSize =
sizeof(Float_t);
315 fParentRowSize = fColSize;
319 Float_t *p = ((Float_t *)fsimpleArray) + fFirstRow;
320 Bool_t isPreSorted = kTRUE;
322 for (Int_t i=0; i < fNumberOfRows;i++,p++) {
323 fSortIndex[i-fFirstRow] = p;
325 if (sample > *p) isPreSorted = kFALSE;
331 if (!isPreSorted)
QSort();
344 TTableSorter::TTableSorter(
const Double_t *simpleArray, Int_t arraySize, Int_t firstRow
346 :fsimpleArray((const Char_t*)simpleArray)
352 if (!fsimpleArray) {MakeZombie();
return; }
357 fColType = TTable::kDouble;
358 fColSize =
sizeof(Double_t);
359 fParentRowSize = fColSize;
363 Double_t *p = ((Double_t *)simpleArray) + fFirstRow;
364 Bool_t isPreSorted = kTRUE;
365 Double_t sample = *p;
366 for (Int_t i=0; i < fNumberOfRows;i++,p++) {
367 fSortIndex[i-fFirstRow] = p;
369 if (sample > *p) isPreSorted = kFALSE;
375 if (!isPreSorted)
QSort();
388 TTableSorter::TTableSorter(
const Long_t *simpleArray, Int_t arraySize, Int_t firstRow
390 :fsimpleArray((const Char_t*)simpleArray)
396 if (!simpleArray) { MakeZombie();
return; }
401 fColType = TTable::kLong;
402 fColSize =
sizeof(Long_t);
403 fParentRowSize = fColSize;
407 Long_t *p = ((Long_t *)simpleArray) + fFirstRow;
408 Bool_t isPreSorted = kTRUE;
410 for (Int_t i=0; i < fNumberOfRows;i++,p++) {
411 fSortIndex[i-fFirstRow] = p;
413 if (sample > *p) isPreSorted = kFALSE;
418 if (!isPreSorted)
QSort();
432 delete [] fIndexArray;
437 if (firstRow > arraySize)
return;
438 fFirstRow = firstRow;
440 fNumberOfRows = arraySize - fFirstRow;
441 if (numberRows > 0) fNumberOfRows = TMath::Min(numberRows,fNumberOfRows);
444 delete [] fSortIndex;
445 if (fNumberOfRows > 0) fSortIndex =
new void*[fNumberOfRows];
453 delete [] fSortIndex; fSortIndex = 0; fNumberOfRows=0;
454 delete [] fIndexArray;
471 #define BINARYSEARCH(valuetype) Int_t TTableSorter::BinarySearch(valuetype value) const {\
472 switch (fColType) { \
473 case TTable::kFloat: \
474 return SelectSearch(Float_t(value)); \
475 case TTable::kInt : \
476 return SelectSearch(Int_t(value)); \
477 case TTable::kLong : \
478 return SelectSearch(Long_t(value)); \
479 case TTable::kShort : \
480 return SelectSearch(Short_t(value)); \
481 case TTable::kDouble : \
482 return SelectSearch(Double_t(value)); \
483 case TTable::kUInt: \
484 return SelectSearch(UInt_t(value)); \
485 case TTable::kULong : \
486 return SelectSearch(ULong_t(value)); \
487 case TTable::kUShort: \
488 return SelectSearch(UShort_t(value)); \
489 case TTable::kBool: \
490 return SelectSearch(Bool_t(value)); \
491 case TTable::kUChar: \
492 return SelectSearch(UChar_t(value)); \
493 case TTable::kChar: \
494 return SelectSearch(Char_t(value)); \
500 Int_t TTableSorter::BSearch(valuetype value) const{ \
501 union { Bool_t Bool; \
514 switch (fColType) { \
515 case TTable::kFloat: \
516 value_.Float = Float_t(value); break; \
517 case TTable::kInt : \
518 value_.Int = Int_t(value); break; \
519 case TTable::kLong : \
520 value_.Long = Long_t(value); break; \
521 case TTable::kShort : \
522 value_.Short = Short_t(value); break; \
523 case TTable::kDouble : \
524 value_.Double= Double_t(value);break; \
525 case TTable::kUInt: \
526 value_.UInt = UInt_t(value); break; \
527 case TTable::kULong : \
528 value_.ULong = ULong_t(value); break; \
529 case TTable::kUShort: \
530 value_.UShort= UShort_t(value);break; \
531 case TTable::kUChar: \
532 value_.UChar = UChar_t(value); break; \
533 case TTable::kChar: \
534 value_.Char = Char_t(value); break; \
535 case TTable::kBool: \
536 value_.Bool = Bool_t(value); break; \
541 return BSearch(&value_); \
543 Int_t TTableSorter::SelectSearch(valuetype value) const { \
544 valuetype **array = (valuetype **)fSortIndex; \
545 Int_t nabove, nbelow, middle; \
546 nabove = fNumberOfRows+1; \
548 while(nabove-nbelow > 1) { \
549 middle = (nabove+nbelow)/2; \
550 if (value == *array[middle-1]) { nbelow = middle; break; } \
551 if (value < *array[middle-1]) nabove = middle; \
552 else nbelow = middle; \
555 ((TTableSorter *)this)->fLastFound = nbelow; \
556 if (nbelow < 0) return nbelow; \
557 return GetIndex(nbelow); \
560 #define COMPAREFLOATVALUES(valuetype) \
561 int TTableSorter::Search##valuetype (const void *elem1, const void **elem2) { \
562 valuetype *value1 = (valuetype *)(elem1); \
563 valuetype *value2 = (valuetype *)(*elem2); \
564 valuetype diff = *value1-*value2; \
566 if (diff > 0) res = 1; \
567 else if (diff < 0) res = -1; \
570 int TTableSorter::Compare##valuetype (const void **elem1, const void **elem2) {\
571 valuetype *value1 = (valuetype *)(*elem1); \
572 valuetype *value2 = (valuetype *)(*elem2); \
573 valuetype diff = *value1-*value2; \
575 if (diff > 0 ) res = 1; \
576 else if (diff < 0) res = -1; \
577 if (res) return res; \
578 return int(value1-value2); \
580 BINARYSEARCH(valuetype)
584 #define COMPAREVALUES(valuetype) \
585 int TTableSorter::Search##valuetype (const void *elem1, const void **elem2) { \
586 valuetype *value1 = (valuetype *)(elem1); \
587 valuetype *value2 = (valuetype *)(*elem2); \
588 return int(*value1-*value2); \
590 int TTableSorter::Compare##valuetype (const void **elem1, const void **elem2) { \
591 valuetype *value1 = (valuetype *)(*elem1); \
592 valuetype *value2 = (valuetype *)(*elem2); \
593 valuetype diff = *value1-*value2; \
594 if (diff ) return diff; \
595 return int(value1-value2); \
597 BINARYSEARCH(valuetype)
599 COMPAREFLOATVALUES(Float_t)
601 COMPAREVALUES(Long_t)
602 COMPAREVALUES(ULong_t)
603 COMPAREVALUES(UInt_t)
604 COMPAREVALUES(Short_t)
605 COMPAREFLOATVALUES(Double_t)
606 COMPAREVALUES(UShort_t)
607 COMPAREVALUES(UChar_t)
608 COMPAREVALUES(Char_t)
609 COMPAREVALUES(Bool_t)
611 #define COMPAREORDER(valuetype) Compare##valuetype
612 #define SEARCHORDER(valuetype) Search##valuetype
621 void **p = (
void **)::bsearch((
void *) value,
628 const Char_t *res = (
const Char_t *)(*p);
629 ((
TTableSorter *)
this)->fLastFound = ((Char_t *)p - (Char_t *)fSortIndex)/
sizeof(
void *);
632 index = fFirstRow + (res - (At(fFirstRow)+ fColOffset))/fParentRowSize;
634 index = ULong_t(res) - ULong_t(fsimpleArray)/fColSize;
646 if (sortedIndex < UInt_t(fNumberOfRows) ) {
647 void *p = fSortIndex[sortedIndex];
649 const Char_t *res = (
const Char_t *)p;
652 indx = fFirstRow + (res - (At(fFirstRow) + fColOffset))/fParentRowSize;
654 indx = (ULong_t(res) - ULong_t(fsimpleArray))/fColSize;
664 int TTableSorter::CompareUChar (
const void *elem1,
const void *elem2)
666 UChar_t *value1 = (UChar_t *)(*elem1);
667 UChar_t *value2 = (UChar_t *)(*elem2);
668 COMPAREVALUES(value1,value2)
674 int TTableSorter::CompareChar (
const void *elem1,
const void *elem2)
676 Char_t *value1 = (Char_t *)(*elem1);
677 Char_t *value2 = (Char_t *)(*elem2);
678 COMPAREVALUES(value1,value2)
695 if (firstRow) *firstRow = -1;
697 Int_t indx = firstIndx;
698 Int_t nRows = GetNRows();
700 while ( indx < nRows &&
fSearchMethod(key,(
const void **)&fSortIndex[indx])){indx++;}
705 count = TMath::Max(0,GetLastFound() - indx + 1);
706 indx = TMath::Max(GetLastFound()+1,firstIndx);
711 while ( indx < nRows &&!
fSearchMethod(key,(
const void **)&fSortIndex[indx])){indx++; count++;}
712 if (firstRow && count) *firstRow = indx-count;
726 if (fSortIndex && fSortIndex[0]) {
727 void *key = fSortIndex[0];
729 while (indx < GetNRows()){
732 key = fSortIndex[indx];
748 assert(fSortIndex!=0);
749 const char *row = At(fFirstRow) + fColOffset;
750 Bool_t isPreSorted = kTRUE;
751 const void *sample = row;
752 for (Int_t i=fFirstRow; i < fFirstRow+fNumberOfRows;i++,row += fParentRowSize) {
753 fSortIndex[i-fFirstRow] = (
char *)row;
756 if (fCompareMethod(&sample,(
const void **)ptr)>0) isPreSorted = kFALSE;
783 indx = GetLastFound();
785 while (indx > 0 && !
fSearchMethod(key,(
const void **)&fSortIndex[indx-1])) indx--;
795 return fParentTable ? fParentTable->GetName():
"";
803 return fParentTable ? fParentTable->GetTitle():
"";
811 return fParentTable ? fParentTable->
GetType():
"";
819 return (
TTable *)fParentTable;
831 fCompareMethod = COMPAREORDER(Float_t);
835 fCompareMethod = COMPAREORDER(Int_t);
839 fCompareMethod = COMPAREORDER(Long_t);
841 case TTable::kShort :
843 fCompareMethod = COMPAREORDER(Short_t);
845 case TTable::kDouble :
847 fCompareMethod = COMPAREORDER(Double_t);
851 fCompareMethod = COMPAREORDER(UInt_t);
853 case TTable::kULong :
855 fCompareMethod = COMPAREORDER(ULong_t);
857 case TTable::kUShort:
859 fCompareMethod = COMPAREORDER(UShort_t);
863 fCompareMethod = COMPAREORDER(UChar_t);
867 fCompareMethod = COMPAREORDER(Char_t);
871 fCompareMethod = COMPAREORDER(Bool_t);
889 CALLQSORT(fCompareMethod));
904 if (!classPtr)
return;
906 if (!classPtr->GetListOfRealData()) classPtr->BuildRealData();
907 if (!(classPtr->GetNdata()))
return;
912 TIter next(classPtr->GetListOfDataMembers());
913 TDataMember *member = 0;
914 while ( (member = (TDataMember *) next()) ) {
915 varname = (Char_t *) member->GetName();
917 if (strcmp(varname,fColName.Data()))
continue;
919 TDataType *memberType = member->GetDataType();
920 types = memberType->GetTypeName();
922 if (!strcmp(
"float", types))
923 fColType = TTable::kFloat ;
924 else if (!strcmp(
"int", types))
925 fColType = TTable::kInt ;
926 else if (!strcmp(
"long", types))
927 fColType = TTable::kLong ;
928 else if (!strcmp(
"short", types))
929 fColType = TTable::kShort ;
930 else if (!strcmp(
"double", types))
931 fColType = TTable::kDouble;
932 else if (!strcmp(
"unsigned int", types))
933 fColType = TTable::kUInt ;
934 else if (!strcmp(
"unsigned long", types))
935 fColType = TTable::kULong ;
936 else if (!strcmp(
"unsigned short", types))
937 fColType = TTable::kUShort;
938 else if (!strcmp(
"unsigned char", types))
939 fColType = TTable::kUChar;
940 else if (!strcmp(
"char", types))
941 fColType= TTable::kChar;
942 else if (!strcmp(
"bool", types))
943 fColType= TTable::kBool;
945 if (fColType != TTable::kNAN) {
947 Int_t globalIndex = 0;
948 if ( (dim = member->GetArrayDim()) ) {
950 if (dim != fColDimensions) {
951 Error(
"LearnTable",
"Wrong dimension");
957 for( Int_t indx=0; indx < fColDimensions; indx++ ){
958 globalIndex *= member->GetMaxIndex(indx);
959 globalIndex += fIndexArray[indx];
962 fColSize = memberType->Size();
963 fColOffset = member->GetOffset() + memberType->Size() * globalIndex;
971 #undef COMPAREFLOATVALUES
virtual TClass * GetRowClass() const
to be documented
virtual Long_t GetRowSize() const
Returns the size (in bytes) of one table row.
virtual Int_t FindFirstKey(const void *key) const
virtual const char * GetTableTitle() const
to be documented
virtual const Char_t * GetType() const
Returns the type of the wrapped C-structure kept as the TNamed title.
Int_t GetIndex(UInt_t sortedIndex) const
returns the original index of the row by its sorted index
virtual const char * GetTableType() const
to be documented
void SetSearchMethod()
Select search function at once.
void BuildSorter(TString &colName, Int_t firstRow, Int_t numberRows)
virtual Long_t GetNRows() const
Returns the number of the used rows for the wrapped table.
Int_t BSearch(const void *value) const
to be documented
virtual TTable * GetTable() const
to be documented
SEARCHMETHOD fSearchMethod
virtual const char * GetTableName() const
to be documented
virtual ~TTableSorter()
to be documented
virtual Int_t CountKey(const void *key, Int_t firstIndx=0, Bool_t bSearch=kTRUE, Int_t *firstRow=0) const
void SetSimpleArray(Int_t arraySize, Int_t firstRow, Int_t numberRows)
Set some common parameteres for the "simple" arrays.
virtual Char_t * Print(Char_t *buf, Int_t n) const
Create IDL table defintion (to be used for XDF I/O)
virtual Int_t CountKeys() const