void ThreadSafeHashSet<T, H>::condenseIfNeeded() { // Посчитаем новое количество элементов и новый load factor. unsigned int oldBucketsNumber = getCurrentBucketsNumber(); unsigned int newBucketsNumber = oldBucketsNumber / growthFactor_; // Число корзин должно быть всегда не меньше числа мьютексов(страйпов). if (newBucketsNumber < mutexNumber_) { return; } // Посчитаем новый, будущий load factor. double newLoadFactor = currentElementsNumber_ / newBucketsNumber; // Проверим, нужно ли нам сокращать таблицу в соответствии с этим newLoadFactor. if (newLoadFactor > extremeLoadFactor_) { return; } // Если мы сюда попали, значит нужно уменьшить количество корзин // Сделаем сначала reHash от нового количества корзин, чтобы // чтобы при resize ничего не потерять // Захватим все мьютексы bool toBeContinued = smartlyGrabAllMutexes(); if (!toBeContinued) { return; } // Если успешно захватили, то рехэш и ресайз. reHash(newBucketsNumber); // И, теперь уменьшим количество корзин buckets_.resize(newBucketsNumber); // Ну и отпустим все мьютексы. releaseAllMutexes(); }
//rehash element from one table to another //Arguments: h- old table, newhash - new table, oldCode - index of the element in old table ( h ) int reHash(HashTable *h, HashTable *newHash, int oldCode){ int oldPrefix = findPrefixGivenCode(h,oldCode); //store values to avoid recalculation int oldChar = findCharGivenCode(h,oldCode); bool isRehashed = findisRehashedGivenCode(h,oldCode); if (oldChar == -1){ //if empty slot return -1 return -1; } else if(isRehashed){ //if already rehashed slot, return prefix return oldPrefix; } else if (oldPrefix == emptyCode){ //if prefix is 0 ((*h)[oldCode]).isRehashed = 1; //re-insert it int t = insertInHashTable(newHash,oldPrefix,oldChar); ((*h)[oldCode]).prefix = t; return ((*h)[oldCode]).prefix; //return prefix where inserted } else{ int k = reHash(h,newHash,oldPrefix); //recursive case int m = insertInHashTable(newHash,k,oldChar); //unfold prefixes and insert when hit 0 ((*h)[oldCode]).prefix = m; ((*h)[oldCode]).isRehashed = 1; return m; } return -1; }
/*Insere um item na tabela, se preciso, aumenta ela*/ void st_lema_insert(Item_lema item) { int i; if(1.0*N/M > 0.5) reHash(); i = hash(key_lema(item), M); heads[i] = NEW(item, heads[i]); N++; }
void rehashIfNeeded(HashMap *map){ int i; List *listOfHashObjects; for(i=0;i<map->capacity;i++){ listOfHashObjects = (List*)get(map->buckets,i); if(listOfHashObjects->length > 3) return reHash(map); } };
/*Insere um item na tabela, se preciso, aumenta ela*/ void st_lema_insert(Item_lema item) { Key_lema v; int i; if(1.0*N/M > 0.5) reHash(); v = key_lema(item); i = hash(v, M); while (!null(i)) i = (i+1) % M; st_lema[i] = item; N++; }
//rehash all elements from one table to another using reHash function defined above int actualRehash(HashTable *h){ //rehash every element of the table SizeOfTable = SizeOfTable * 2; HashTable newHash; initializeTable(&newHash); for (int i = 2; i < SizeOfTable/2; i++){ reHash(h,&newHash,i); } destroyHashTable(h); //destroy the old table (*h) = newHash; return 0; }
void ThreadSafeHashSet<T, H>::expandIfNeeded() { // Проверим, нужно ли вообще расширяться // с помощью loadFactor. if (getCurrentLoadFactor() < extremeLoadFactor_) { return; } // Если получилось захватить первый мьютекс // так, что никто не успел расширить // контейнер до нас, то расширять придётся // как раз нам. bool toBeContinued = smartlyGrabAllMutexes(); if (!toBeContinued) { return; } // Расширимся... unsigned int newBucketsNumber = growthFactor_ * getCurrentBucketsNumber(); buckets_.resize(newBucketsNumber); // Затем нужно перехешироваться. reHash(newBucketsNumber); // Отпустим все мьютексы. releaseAllMutexes(); }
//Insert the Item (key, v) in the table //If key already exists in the table then change the associated value to v //Re-hash if the table becomes 50% full // IMPLEMENT void HashTable::insert(string key, int v) { int index = h(key, size); if(hTable[index] != nullptr) { if(hTable[index]->key != key) { while(hTable[index] != nullptr) { if(index == (size - 1)) { index = 0; } else { index++; } } hTable[index] = new Item(key, v); nItems++; } else { hTable[index]->value += v; } } else { hTable[index] = new Item(key, v); nItems++; } if( (loadFactor()) >= MAX_LOAD_FACTOR) { reHash(); } }