/// Makes value.first map to value.second unless value.first is already /// present in the map - in that case nothing is done. If p is the returned /// pair then *p.first.first is the value that value.first maps to after the insert /// and p.second is true if an insertion was performed. *p.first.first will not /// equal value.second if an insertion was not performed - unless the /// inserted value equals the already present value. p.first.second is an /// internal monomial that equals value.first. std::pair< std::pair<const mapped_type*, ConstMonomial>, bool> insert(const value_type& value) { const mgb::mtbb::mutex::scoped_lock lockGuard(mInsertionMutex); // We can load mMap as std::memory_order_relaxed because we have already // synchronized with all other mutators by locking mInsertionMutex; auto map = mMap.load(std::memory_order_relaxed); // this is a loop since it is possible to set the growth factor and // the initial size so low that several rounds are required. This should // only happen when debugging as otherwise such low parameters are // not a good idea. while (mCapacityUntilGrowth == 0) { // Resize the table by making a bigger one and using that instead. if (map->bucketCount() > // check overflow std::numeric_limits<size_t>::max() / GrowthFactor) { throw std::bad_alloc(); } const size_t newBucketCount = map->bucketCount() * GrowthFactor; auto nextMap = make_unique<FixedSizeMap>(newBucketCount, std::move(*map)); mOldMaps.emplace_back(map); mCapacityUntilGrowth = maxEntries(nextMap->bucketCount()) - maxEntries(map->bucketCount()); // Store with std::memory_order_seq_cst to force a memory flush so that // readers see the new table as soon as possible. map = nextMap.release(); mMap.store(map, std::memory_order_seq_cst); } MATHICGB_ASSERT(mCapacityUntilGrowth > 0); auto p = map->insert(value); if (p.second) --mCapacityUntilGrowth; return p; }
void FixedSizeBucketAllocatorBase::debugDump() const { std::cerr << "Bucket allocator (Size: " << _size << " bytes)," << bucketCount() << "buckets." << std::endl; if(!empty()) { xsize i = 0; Bucket *b = _first; while(b) { std::cerr << " Bucket" << i++ << std::endl; b->debugDump(); b = b->next(); } } else { std::cerr << " Empty." << std::endl; } }
void Commands::handleCommands() { std::string line, first, second, third; do { std::string temp; int count = 0; first = second = third = ""; std::getline(std::cin, line); std::stringstream lineStream1(line); std::stringstream lineStream2(line); while (lineStream1 >> temp) count++; if (count>3) { std::cout << "INVALID" << std::endl; continue; } lineStream2 >> first; lineStream2 >> second; lineStream2 >> third; line = first + " " + second + " " + third; if (line.find(" ") == -1) first = line; else { first = line.substr(0, line.find(" ")); line.erase(0, line.find(" ") + 1); if (line.find(" ") == -1) second = line; else { second = line.substr(0, line.find(" ")); line.erase(0, line.find(" ") + 1); third = line; } } if (first == "CREATE" && second != "" && third != "") create(second, third); else if (first == "LOGIN" && second != "" && third != "") login(second, third); else if (first == "LOGIN" && second == "COUNT" && third == "") loginCount(); else if (first == "REMOVE") remove(second); else if (first == "DEBUG" && (second == "ON" || second == "OFF")) debug(debugFlag, second); else if (first == "BUCKET" && second == "COUNT") bucketCount(); else if (first == "LOAD" && second == "FACTOR") loadFactor(); else if (first == "CLEAR") { logins.deleteBucket(); std::cout << "CLEARED" << std::endl; } else if (first == "QUIT") std::cout << "GOODBYE" << std::endl; else if (first == "MAX" && second == "BUCKET" && third == "SIZE") maxBucketSize(); else std::cout << "INVALID" << std::endl; } while (first != "QUIT"); }