28 #ifndef INCresourceLibh 29 #define INCresourceLibh 38 #ifndef assert // allow use of epicsAssert.h 44 #include "libComAPI.h" 75 template <
class T,
class ID>
81 void show (
unsigned level )
const;
84 T *
remove (
const ID &idIn );
86 T *
lookup (
const ID &idIn )
const;
101 unsigned nextSplitIndex;
103 unsigned hashIxSplitMask;
104 unsigned nBitsHashIxSplitMask;
105 unsigned logBaseTwoTableSize;
108 T * find (
tsSLList<T> & list,
const ID & idIn )
const;
110 unsigned tableSize ()
const;
111 bool setTableSizePrivate (
unsigned logBaseTwoTableSize );
114 static unsigned resTableBitMask (
const unsigned nBits );
124 template <
class T,
class ID >
132 T & operator * ()
const;
133 T * operator -> ()
const;
142 void findNextEntry ();
151 template <
class T,
class ID >
159 const T & operator * ()
const;
160 const T * operator -> ()
const;
169 void findNextEntry ();
198 template <
class T,
unsigned MIN_INDEX_WIDTH=4u,
199 unsigned MAX_ID_WIDTH =
sizeof(T)*CHAR_BIT>
202 intId (
const T &idIn);
205 const T getId()
const;
224 template <
class ITEM>
241 template <
class ITEM>
246 void setId (
unsigned newId);
263 const char * resourceName()
const;
264 void show (
unsigned level)
const;
279 template <
class T,
class ID>
281 pTable ( 0 ), nextSplitIndex ( 0 ), hashIxMask ( 0 ),
282 hashIxSplitMask ( 0 ), nBitsHashIxSplitMask ( 0 ),
283 logBaseTwoTableSize ( 0 ), nInUse ( 0 ) {}
285 template <
class T,
class ID>
288 return ( 1 << nBits ) - 1;
296 template <
class T,
class ID>
299 if ( this->pTable ) {
301 tsSLList<T> & list = this->pTable [ this->hash(idIn) ];
304 while ( pItem.
valid () ) {
305 const ID & idOfItem = *pItem;
306 if ( idOfItem == idIn ) {
326 template <
class T,
class ID>
329 const unsigned N = this->tableSize ();
330 for (
unsigned i = 0u;
i < N;
i++ ) {
331 while ( T * pItem = this->pTable[
i].
get() ) {
332 destination.
add ( *pItem );
341 template <
class T,
class ID>
344 if ( this->pTable ) {
345 tsSLList<T> & list = this->pTable [ this->hash ( idIn ) ];
346 return this->find ( list, idIn );
356 template <
class T,
class ID>
361 if ( h0 >= this->nextSplitIndex ) {
364 return h & this->hashIxSplitMask;
370 template <
class T,
class ID>
373 const unsigned N = this->tableSize ();
375 printf (
"Hash table with %u buckets and %u items of type %s installed\n",
376 N, this->nInUse,
typeid(T).name() );
378 if ( level >= 1u && N ) {
382 while ( pList < & this->pTable[N] ) {
384 while ( pItem.
valid () ) {
387 pItem.
pointer()->show ( level - 2u );
396 unsigned maxEntries = 0u;
398 for (
unsigned i = 0u;
i < N;
i++ ) {
401 while ( pItem.
valid () ) {
403 pItem->show ( level );
411 if ( count > maxEntries ) {
419 double stdDev = sqrt( XX / N - mean * mean );
421 "entries per bucket: mean = %f std dev = %f max = %u\n",
422 mean, stdDev, maxEntries );
423 printf(
"%u empty buckets\n", empty);
424 if ( X != this->nInUse ) {
425 printf (
"this->nInUse didnt match items counted which was %f????\n", X );
431 template <
class T,
class ID>
434 const unsigned N = this->tableSize ();
436 if ( this->pTable ) {
437 assert ( this->nextSplitIndex <= this->hashIxMask + 1 );
438 assert ( this->hashIxMask );
439 assert ( this->hashIxMask == ( this->hashIxSplitMask >> 1 ) );
440 assert ( this->hashIxSplitMask );
441 assert ( this->nBitsHashIxSplitMask );
442 assert ( resTableBitMask ( this->nBitsHashIxSplitMask )
443 == this->hashIxSplitMask );
444 assert ( this->logBaseTwoTableSize );
445 assert ( this->nBitsHashIxSplitMask <= this->logBaseTwoTableSize );
448 assert ( this->nextSplitIndex == 0 );
449 assert ( this->hashIxMask == 0 );
450 assert ( this->hashIxSplitMask == 0 );
451 assert ( this->nBitsHashIxSplitMask == 0 );
452 assert ( this->logBaseTwoTableSize == 0 );
456 for (
unsigned i = 0u;
i < N;
i++ ) {
459 while ( pItem.
valid () ) {
467 assert ( total == this->nInUse );
474 template <
class T,
class ID>
477 const unsigned N = this->tableSize ();
478 for (
unsigned i = 0u;
i < N;
i++ ) {
480 while ( pItem.
valid () ) {
492 template <
class T,
class ID>
495 const unsigned N = this->tableSize ();
496 for (
unsigned i = 0u;
i < N;
i++ ) {
499 while ( pItem.
valid () ) {
508 template <
class T,
class ID>
514 template <
class T,
class ID>
517 if ( this->pTable ) {
518 return ( this->hashIxMask + 1 ) + this->nextSplitIndex;
527 template <
class T,
class ID>
530 if ( newTableSize == 0u ) {
538 unsigned newMask = newTableSize - 1;
540 for ( nbits = 0; nbits <
sizeof (newTableSize) * CHAR_BIT; nbits++ ) {
541 unsigned nBitsMask = resTableBitMask ( nbits );
542 if ( ( newMask & ~nBitsMask ) == 0){
546 setTableSizePrivate ( nbits );
549 template <
class T,
class ID>
553 if ( this->logBaseTwoTableSize >= logBaseTwoTableSizeIn ) {
558 if ( logBaseTwoTableSizeIn < 4 ) {
559 logBaseTwoTableSizeIn = 4;
562 const unsigned newTableSize = 1 << logBaseTwoTableSizeIn;
563 # if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) 564 const unsigned oldTableSize = this->pTable ? 1 << this->logBaseTwoTableSize : 0;
566 const unsigned oldTableOccupiedSize = this->tableSize ();
571 ::
operator new ( newTableSize *
sizeof (
tsSLList<T> ) );
574 if ( ! this->pTable ) {
582 for ( i = 0u; i < oldTableOccupiedSize; i++ ) {
585 for ( i = oldTableOccupiedSize; i < newTableSize; i++ ) {
591 # if ! defined (__GNUC__) || __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 92 ) 592 for ( i = 0; i < oldTableSize; i++ ) {
593 this->pTable[
i].~tsSLList<T>();
597 if ( ! this->pTable ) {
598 this->hashIxSplitMask = resTableBitMask ( logBaseTwoTableSizeIn );
599 this->nBitsHashIxSplitMask = logBaseTwoTableSizeIn;
600 this->hashIxMask = this->hashIxSplitMask >> 1;
601 this->nextSplitIndex = 0;
604 operator delete ( this->pTable );
605 this->pTable = pNewTable;
606 this->logBaseTwoTableSize = logBaseTwoTableSizeIn;
611 template <
class T,
class ID>
617 if ( this->nextSplitIndex > this->hashIxMask ) {
618 bool success = this->setTableSizePrivate ( this->nBitsHashIxSplitMask + 1 );
622 this->nBitsHashIxSplitMask += 1;
623 this->hashIxSplitMask = resTableBitMask ( this->nBitsHashIxSplitMask );
624 this->hashIxMask = this->hashIxSplitMask >> 1;
625 this->nextSplitIndex = 0;
629 tsSLList<T> tmp ( this->pTable[ this->nextSplitIndex ] );
630 this->nextSplitIndex++;
631 T *pItem = tmp.
get();
634 this->pTable[index].add ( *pItem );
642 template <
class T,
class ID>
645 if ( ! this->pTable ) {
646 this->setTableSizePrivate ( 10 );
648 else if ( this->nInUse >= this->tableSize() ) {
649 this->splitBucket ();
651 if ( this->find ( list, res ) != 0 ) {
656 if ( this->find ( list, res ) != 0 ) {
672 template <
class T,
class ID>
676 while ( pItem.
valid () ) {
677 const ID & idOfItem = *pItem;
678 if ( idOfItem == idIn ) {
689 template <
class T,
class ID>
692 operator delete ( this->pTable );
699 template <
class T,
class ID>
708 template <
class T,
class ID>
714 template <
class T,
class ID>
720 template <
class T,
class ID>
730 template <
class T,
class ID >
732 index ( 0 ), pResTable ( & tableIn )
734 this->findNextEntry ();
737 template <
class T,
class ID >
739 iter (
tsSLList<T>::invalidIter() ),
740 index ( 0 ), pResTable ( 0 )
744 template <
class T,
class ID >
747 if ( this->pResTable ) {
748 while ( this->index < this->pResTable->tableSize() ) {
749 this->iter = this->pResTable->pTable[this->index++].firstIter ();
750 if ( this->iter.valid () ) {
757 template <
class T,
class ID >
760 return this->iter.valid ();
763 template <
class T,
class ID >
767 return ( this->pResTable == rhs.pResTable
768 && this->index == rhs.index
769 && this->iter == rhs.iter );
772 template <
class T,
class ID >
773 inline bool resTableIter<T,ID>::operator !=
779 template <
class T,
class ID >
783 this->pResTable = rhs.pResTable;
784 this->index = rhs.index;
785 this->iter = rhs.iter;
789 template <
class T,
class ID >
792 return this->iter.operator * ();
795 template <
class T,
class ID >
798 return this->iter.operator -> ();
801 template <
class T,
class ID >
805 if ( ! this->iter.valid() ) {
806 this->findNextEntry ();
811 template <
class T,
class ID >
819 template <
class T,
class ID >
822 return this->iter.pointer ();
829 template <
class T,
class ID >
831 index ( 0 ), pResTable ( & tableIn )
833 this->findNextEntry ();
836 template <
class T,
class ID >
838 iter (
tsSLList<T>::invalidIter() ),
839 index ( 0 ), pResTable ( 0 )
843 template <
class T,
class ID >
846 if ( this->pResTable ) {
847 while ( this->index < this->pResTable->tableSize() ) {
848 const tsSLList<T> * pList = & this->pResTable->pTable[this->index++];
850 if ( this->iter.valid () ) {
857 template <
class T,
class ID >
860 return this->iter.valid ();
863 template <
class T,
class ID >
867 return ( this->pResTable == rhs.pResTable
868 && this->index == rhs.index
869 && this->iter == rhs.iter );
872 template <
class T,
class ID >
873 inline bool resTableIterConst<T,ID>::operator !=
879 template <
class T,
class ID >
883 this->pResTable = rhs.pResTable;
884 this->index = rhs.index;
885 this->iter = rhs.iter;
889 template <
class T,
class ID >
892 return this->iter.operator * ();
895 template <
class T,
class ID >
898 return this->iter.operator -> ();
901 template <
class T,
class ID >
905 if ( ! this->iter.valid() ) {
906 this->findNextEntry ();
911 template <
class T,
class ID >
919 template <
class T,
class ID >
922 return this->iter.pointer ();
929 intId<unsigned, 8u, sizeof(unsigned)*CHAR_BIT> ( idIn ) {}
934 template <
class ITEM>
938 template <
class ITEM>
942 template <
class ITEM>
953 template <
class ITEM>
963 template <
class ITEM>
968 item.chronIntIdRes<ITEM>::setId (allocId++);
981 template <
class ITEM>
989 template <
class ITEM>
1003 template <
class T,
unsigned MIN_INDEX_WIDTH,
unsigned MAX_ID_WIDTH>
1010 template <
class T,
unsigned MIN_INDEX_WIDTH,
unsigned MAX_ID_WIDTH>
1014 return this->
id == idIn.
id;
1020 template <
class T,
unsigned MIN_INDEX_WIDTH,
unsigned MAX_ID_WIDTH>
1031 template <
class T >
1033 unsigned MAX_ID_WIDTH,
const T &
id )
1050 unsigned width = MAX_ID_WIDTH;
1053 hashid ^= hashid>>width;
1054 }
while (width>MIN_INDEX_WIDTH);
1067 template <
class T,
unsigned MIN_INDEX_WIDTH,
unsigned MAX_ID_WIDTH>
1070 return integerHash ( MIN_INDEX_WIDTH, MAX_ID_WIDTH, this->
id );
1080 inline bool stringId::operator ==
1083 if (this->pStr!=
NULL && idIn.pStr!=
NULL) {
1084 return strcmp(this->pStr,idIn.pStr)==0;
1097 #ifdef instantiateRecourceLib 1105 if (typeIn==copyString) {
1106 unsigned nChars = strlen (idIn) + 1u;
1107 this->pStr =
new char [nChars];
1108 memcpy ( (
void *) this->pStr, idIn, nChars );
1121 printf (
"resource id = %s\n", this->pStr);
1133 if (this->allocType==copyString) {
1134 if (this->pStr!=
NULL) {
1151 delete []
const_cast<char *
>(this->pStr);
1167 #endif // if instantiateRecourceLib is defined 1169 #endif // INCresourceLibh
unsigned int epicsStrHash(const char *str, unsigned int seed)
epics::pvData::BitSetPtr empty
#define assert(exp)
Declare that a condition should be true.
tsSLIterConst< T > firstIter() const
resTableIter< T, ID > iterator
const T * pointer() const
unsigned numEntriesInstalled() const
Internal: bucket item structure.
chronIntId(const unsigned &idIn)
bool operator==(const resTableIterConst< T, ID > &rhs) const
void show(unsigned level) const
const T * operator->() const
T * lookup(const ID &idIn) const
void traverse(void(T::*pCB)())
void setTableSize(const unsigned newTableSize)
resTableIndex hash() const
stringId(const char *idIn, allocationType typeIn=copyString)
void idAssignAdd(ITEM &item)
void removeAll(tsSLList< T > &destination)
void traverseConst(void(T::*pCB)() const ) const
virtual ~chronIntIdResTable()
bool operator==(const resTableIter< T, ID > &rhs) const
resTableIter< T, ID > & operator++()
const T * pointer() const
const char * resourceName() const
resTableIterConst< T, ID > iteratorConst
T * remove(const ID &idIn)
const T & operator*() const
void show(unsigned level) const
resTableIndex integerHash(unsigned MIN_INDEX_WIDTH, unsigned MAX_ID_WIDTH, const T &id)
void remove(T &itemBefore)
resTableIndex hash() const
resTableIterConst< T, ID > & operator++()
bool operator!=(const epics::pvData::shared_vector< A > &a, const epics::pvData::shared_vector< B > &b)
bool operator==(const epics::pvData::shared_vector< A > &a, const epics::pvData::shared_vector< B > &b)