bool BitSet::deleteElement(unsigned long value){ if( (value > maxElementValue) || ((bitRepresentation(value) & set[bucketNumber(value)]) == 0) ){ return false; } numItems--; unsigned long valRm = bitRepresentation(value); set[bucketNumber(value)] ^= valRm; return true; }
bool BitSet::addElement(unsigned long value){ if( (value > maxElementValue) || ((bitRepresentation(value) & set[bucketNumber(value)]) != 0) ){ return false; } numItems++; unsigned long valAd = bitRepresentation(value); set[bucketNumber(value)] |= valAd; return true; }
/* * Search for a given key value and return the bucket and UtlLink for it. * Return true if the key was found, and false if not. */ bool UtlHashBag::lookup(const UtlContainable* key, ///< The key to locate. UtlChain*& bucket, /**< The bucket list header in which it belongs. * This is set regardless of whether or not the * key was found in the table. */ UtlLink*& link /**< If the key was found, the UtlLink for entry. * If the key was not found, this is NULL. */ ) const { UtlLink* check; size_t keyHash = key->hash(); bucket = &mpBucket[bucketNumber(keyHash)]; for (link = NULL, check = static_cast<UtlLink*>(bucket->listHead()); ( !link // not found && check // not end of list && check->hash <= keyHash // hash list is ordered, so if > then it's not in the list ); check = static_cast<UtlLink*>(check->UtlChain::next) ) { if (check->hash == keyHash && check->data->isEqual(key)) { link = check; // found it } } return link != NULL; }
bool BitSet::isMember(unsigned long value){ unsigned long val = bitRepresentation(value); if( (value > maxElementValue) || ((val & set[bucketNumber(value)])== 0) ) return false; else return true; }
/* * Allocate additional buckets and redistribute existing contents. * This should only be called through resizeIfNeededAndSafe. */ void UtlHashBag::resize() { // already holding the mContainerLock UtlChain* newBucket; size_t newBucketBits; // if an iterator had prevented resizing while many elements were added, // we might need to double more than once to restore the target ratio. for (newBucketBits = mBucketBits+1; mElements / NUM_HASHBAG_BUCKETS(newBucketBits) >= 3; newBucketBits++ ) { } // allocate the new buckets newBucket = new UtlChain[NUM_HASHBAG_BUCKETS(newBucketBits)]; if (newBucket) { // save the old buckets until we move the entries out of them UtlChain* oldBucket = mpBucket; size_t numOldBuckets = numberOfBuckets(); // put in the new buckets mBucketBits = newBucketBits; mpBucket = newBucket; // move all the entries to the new buckets size_t old; size_t toBeMoved; for (old = 0, toBeMoved = mElements; old < numOldBuckets && toBeMoved; old++ ) { while(!oldBucket[old].isUnLinked()) // old bucket is not empty yet { UtlLink* link = static_cast<UtlLink*>(oldBucket[old].head()); link->detachFromList(&oldBucket[old]); insert(link, &mpBucket[bucketNumber(link->hash)]); toBeMoved--; } } delete [] oldBucket; // finished with the old empty buckets } else { assert(newBucket); // failed to allocate new buckets } }
BitSet::BitSet(unsigned maxValue){ numItems = 0; numBuckets = (bucketNumber(maxValue) + 1); maxElementValue = maxValue-1; set = new unsigned long[numBuckets]; for(unsigned i = 0; i<numBuckets;i++) set[i] = 0; }
UtlContainable* UtlHashBag::insert(UtlContainable* insertedContainable) { if (insertedContainable) // NULL keys are not allowed { OsLock take(mContainerLock); UtlLink* link; link = UtlLink::get(); link->data = insertedContainable; link->hash = insertedContainable->hash(); mElements++; insert(link, &mpBucket[bucketNumber(link->hash)]); } return insertedContainable; }
/** * Removed the designated object by reference * (as opposed to searching for an equality match). * * @return the object if successful, otherwise null */ UtlContainable* UtlHashBag::removeReference(const UtlContainable* object) { UtlContainable* removed = NULL; if (object) { size_t keyHash = object->hash(); OsLock take(mContainerLock); UtlLink* link; UtlChain* bucket; UtlLink* check; bucket = &mpBucket[bucketNumber(keyHash)]; for (link = NULL, check = static_cast<UtlLink*>(bucket->listHead()); ( !link // not found && check // not end of list && check->hash <= keyHash // hash list is ordered, so if > then it's not in the list ); check = check->next() ) { if (check->data == object) { link = check; // found it } } if (link) { notifyIteratorsOfRemove(link); link->detachFromList(bucket); removed = link->data; link->release(); mElements--; } } return removed; }