Пример #1
0
int main(int argc, char* argv[])
{
  std::ifstream in;

  openFile(argv[1],in);

  auto us = readFile<std::unordered_set<std::string>>(in);

  std::cout << "Read " << us.size() << " words from " << argv[1] << ".\n\n";
  std::cout << "Hashtable load factor is: " << us.load_factor() << ".\n";

  auto bc = us.bucket_count();
  std::cout << "Bucket count is: " << us.bucket_count() << ".\n";
  for (int b = 0; b < bc; ++b)
  {
    if (us.bucket_size(b)) 
    {
      std::cout << "Bucket " << b << " contains " << us.bucket_size(b) << " items.\n";
      if (us.bucket_size(b) > 1)
      {
        std::copy(us.cbegin(b),us.cend(b), std::ostream_iterator<std::string>(std::cout," "));
        std::cout << std::endl;
      }
    }
  }
}
Пример #2
0
 /**
  * Build an accumulator to estimate event rates.
  *
  * @param measurement_period over what time period we want to
  *   measure message rates
  * @param sampling_period how often do we want to measure message
  *   rates.  Must be smaller than @a measurement_period.
  * @throw std::invalid_argument if the measurement period is not a
  *   multiple of the sampling period.
  */
 event_rate_estimator(
     duration_type measurement_period,
     duration_type sampling_period = duration_type(1))
     : buckets_(bucket_count(measurement_period, sampling_period))
     , sampling_period_(sampling_period)
     , running_total_()
     , last_bucket_()
     , end_pos_(buckets_.size()) {
 }
Пример #3
0
 std::pair<typename VectorHashTable<Parms>::iterator, bool>
 VectorHashTable<Parms>::insert(const value_type & d) 
 {
   MutableFindIterator j(this, parms_.key(d));
   vector_iterator i = vector_.begin() + j.i;
   if (!parms_.is_multi && !j.at_end())
     return std::pair<iterator,bool>(iterator(i,this),false);
   if (load_factor() > .92) {
     resize(bucket_count()*2);
     return insert(d);
   } 
   if (parms_.is_multi) 
     while(!j.at_end()) j.adv();
   *(vector_.begin() + j.i) = d;
   ++size_;
   return std::pair<iterator,bool>(iterator(i,this),true);
 }
Пример #4
0
 size_t constrain_hash (const T& key)
 {
     return __constrain_hash(t_hash(key), bucket_count());
 }
Пример #5
0
//---------------------------------------------
//mining frequent itemsets from database
//---------------------------------------------
void MineAllPats()
{
	ITEM_COUNTER* pfreqitems;
	int *pitem_order_map;
	double ntotal_occurrences;

	clock_t start, start_mining;;

	int i;
	if(goparameters.bresult_name_given)
		gpfsout = new FSout(goparameters.pat_filename);

	start_mining = clock();

	gntotal_patterns = 0;
	gnmax_pattern_len = 0;
	gntotal_singlepath = 0;

	gndepth = 0;
	gntotal_call = 0;
	gpdata = new Data(goparameters.data_filename);

	//count frequent items in original database
	pfreqitems = NULL;
	start = clock();
	goDBMiner.ScanDBCountFreqItems(&pfreqitems);
	//goTimeTracer.mdInitial_count_time = (double)(clock()-start)/CLOCKS_PER_SEC;

	gppat_counters = new int[gnmax_trans_len];
	//goMemTracer.IncBuffer(gnmax_trans_len*sizeof(int));
	for(i=0;i<gnmax_trans_len;i++)
		gppat_counters[i] = 0;

	if(gntotal_freqitems==0)
		delete gpdata;
	else if(gntotal_freqitems==1)
	{
		gnmax_pattern_len = 1;
		OutputOnePattern(pfreqitems[0].item, pfreqitems[0].support);
		delete gpdata;
	}
	else if(gntotal_freqitems>1)
	{
		gpheader_itemset = new int[gntotal_freqitems];
		//goMemTracer.IncBuffer(gntotal_freqitems*sizeof(int));

		//an array which maps an item to its frequency order; the most infrequent item has order 0
		pitem_order_map = new int[gnmax_item_id];
		for(i=0;i<gnmax_item_id;i++)
			pitem_order_map[i] = -1;
		for(i=0;i<gntotal_freqitems;i++)
			pitem_order_map[pfreqitems[i].item] = i;

		//if the number of frequent items in a conditonal database is smaller than maximal bucket size, use bucket counting technique
		if(gntotal_freqitems <= MAX_BUCKET_SIZE)
		{
			gpbuckets = new int[(1<<gntotal_freqitems)];
			memset(gpbuckets, 0, sizeof(int)*(1<<gntotal_freqitems));
			goDBMiner.ScanDBBucketCount(pitem_order_map, gpbuckets);
			bucket_count(gpbuckets, gntotal_freqitems, pfreqitems);
			delete []gpbuckets;
			delete gpdata;
			delete []pitem_order_map;
		}
		else
		{
			HEADER_TABLE pheader_table;

			goAFOPTMiner.Init(MIN(gnmax_trans_len, gntotal_freqitems+1));
			gpbuckets = new int[(1<<MAX_BUCKET_SIZE)];
			//goMemTracer.IncBuffer(sizeof(int)*(1<<MAX_BUCKET_SIZE));

			//initialize header table
			start = clock();
			pheader_table = new HEADER_NODE[gntotal_freqitems];
			//goMemTracer.IncBuffer(sizeof(HEADER_NODE)*gntotal_freqitems);
			ntotal_occurrences = 0;
			for(i=0;i<gntotal_freqitems;i++)
			{
				pheader_table[i].item = pfreqitems[i].item;
				pheader_table[i].nsupport = pfreqitems[i].support;
				pheader_table[i].parray_conddb = NULL;
				pheader_table[i].order = i;
				ntotal_occurrences += pfreqitems[i].support;
			}

			//to choose a proper representation format for each conditional database
			if((double)goparameters.nmin_sup/gndb_size>=BUILD_TREE_MINSUP_THRESHOLD || 
				ntotal_occurrences/(gndb_size*gntotal_freqitems)>=BUILD_TREE_AVGSUP_THRESHOLD ||
				gntotal_freqitems<=BUILD_TREE_ITEM_THRESHOLD )
			{
				for(i=0;i<gntotal_freqitems;i++)
					pheader_table[i].flag = AFOPT_FLAG;
			}
			else
			{
				for(i=0;i<gntotal_freqitems-BUILD_TREE_ITEM_THRESHOLD;i++)
					pheader_table[i].flag = 0;
				for(i=MAX(0, gntotal_freqitems-BUILD_TREE_ITEM_THRESHOLD);i<gntotal_freqitems;i++)
					pheader_table[i].flag = AFOPT_FLAG;
			}

			//scan database to construct conditional databases and do bucket counting
			memset(gpbuckets, 0, sizeof(int)*(1<<MAX_BUCKET_SIZE));
			goDBMiner.ScanDBBuildCondDB(pheader_table, pitem_order_map, gntotal_freqitems, gpbuckets);
			//goTimeTracer.mdInitial_construct_time = (double)(clock()-start)/CLOCKS_PER_SEC;
			//goMemTracer.mninitial_struct_size = //goMemTracer.mnArrayDB_size+//goMemTracer.mnAFOPTree_size+sizeof(int)*(1<<MAX_BUCKET_SIZE);			
			bucket_count(gpbuckets, MAX_BUCKET_SIZE, &(pfreqitems[gntotal_freqitems-MAX_BUCKET_SIZE]));

			delete []pitem_order_map;
			delete gpdata;
			
			//mining frequent itemsets in depth first order
			if((double)goparameters.nmin_sup/gndb_size>=BUILD_TREE_MINSUP_THRESHOLD ||
				ntotal_occurrences/(gndb_size*gntotal_freqitems)>=BUILD_TREE_AVGSUP_THRESHOLD ||
				gntotal_freqitems<=BUILD_TREE_ITEM_THRESHOLD)
				goAFOPTMiner.DepthAFOPTGrowth(pheader_table, gntotal_freqitems, 0);
			else
			{
				goArrayMiner.DepthArrayGrowth(pheader_table, gntotal_freqitems);
				goAFOPTMiner.DepthAFOPTGrowth(pheader_table, gntotal_freqitems, gntotal_freqitems-BUILD_TREE_ITEM_THRESHOLD);
			}

			delete []pheader_table;
			//goMemTracer.DecBuffer(gntotal_freqitems*sizeof(HEADER_NODE));
			delete []gpbuckets;
			//goMemTracer.DecBuffer(sizeof(int)*(1<<MAX_BUCKET_SIZE));

		}
		delete []gpheader_itemset;
		//goMemTracer.DecBuffer(gntotal_freqitems*sizeof(int));
	}
	delete []pfreqitems;
	//goMemTracer.DecBuffer(gntotal_freqitems*sizeof(ITEM_COUNTER));
	
	if(goparameters.bresult_name_given)
		delete gpfsout;
	//goTimeTracer.mdtotal_running_time = (double)(clock()-start_mining)/CLOCKS_PER_SEC;

	PrintSummary();
	delete []gppat_counters;
	//goMemTracer.DecBuffer(gnmax_trans_len*sizeof(int));
}
Пример #6
0
//-----------------------------------------------------------------------------------
//mining frequent itemsets from a conditional database represented by an AFOPT-tree
//------------------------------------------------------------------------------------
void CAFOPTMine::DepthAFOPTGrowth(HEADER_TABLE pheader_table, int num_of_freqitems, int nstart_pos)
{
	int	i;
	AFOPT_NODE *pcurroot;
	ITEM_COUNTER* pnewfreqitems;
	int *pitem_suporder_map;
	int num_of_newfreqitems;
	HEADER_TABLE pnewheader_table;
	int k, nend_pos;
	ARRAY_NODE *pitem_list;

	clock_t start;

	gntotal_call++;

	pnewfreqitems = new ITEM_COUNTER[num_of_freqitems];
	//goMemTracer.IncBuffer(num_of_freqitems*sizeof(ITEM_COUNTER));
	pitem_suporder_map = new int[num_of_freqitems];
	//goMemTracer.IncBuffer(num_of_freqitems*sizeof(int));

	if(gnmax_trans_len<gndepth+1)
		gnmax_trans_len = gndepth+1;
	nend_pos = num_of_freqitems-MAX_BUCKET_SIZE;
	for(k=nstart_pos;k<nend_pos;k++)
	{
		OutputOnePattern(pheader_table[k].item, pheader_table[k].nsupport);
		pcurroot = pheader_table[k].pafopt_conddb;
		if(pcurroot==NULL)
			continue;

  		gpheader_itemset[gndepth] = pheader_table[k].item;
		gndepth++;

		//if the tree contains only one single branch, then directly enumerate all frequent itemsets from the tree
		if(pcurroot->flag>0)
		{
			pitem_list = pcurroot->pitemlist;
			for(i=0;i<pcurroot->flag && pitem_list[i].support>=gnmin_sup;i++)
			{
				pnewfreqitems[i].item = pheader_table[pitem_list[i].order].item;
				pnewfreqitems[i].support = pitem_list[i].support;
			}

			OutputSinglePath(pnewfreqitems, i);

			if(pcurroot->flag>1 && pitem_list[0].order<nend_pos)
			{
				InsertTransaction(pheader_table, pitem_list[0].order, &(pitem_list[1]), pcurroot->flag-1);
			}
			delete []pitem_list;
			//goMemTracer.DelSingleBranch(pcurroot->flag);
			delete pcurroot;
			//goMemTracer.DelOneAFOPTNode();
			pheader_table[k].pafopt_conddb = NULL;
		}
		else if(pcurroot->flag==0)
		{

			//count frequent items from AFOPT-tree
			for(i=k+1;i<num_of_freqitems;i++)
				pitem_suporder_map[i] = 0;
			start = clock();
			CountFreqItems(pcurroot, pitem_suporder_map);
			//goTimeTracer.mdAFOPT_count_time += (double)(clock()-start)/CLOCKS_PER_SEC;
			num_of_newfreqitems = 0;
			for(i=k+1;i<num_of_freqitems;i++)
			{
				if(pitem_suporder_map[i]>=gnmin_sup)
				{
					pnewfreqitems[num_of_newfreqitems].item = pheader_table[i].item;
					pnewfreqitems[num_of_newfreqitems].support = pitem_suporder_map[i];
					pnewfreqitems[num_of_newfreqitems].order = i;
					num_of_newfreqitems++;
				}
				pitem_suporder_map[i] = -1;
			}
			if(num_of_newfreqitems>0)
			{
				qsort(pnewfreqitems, num_of_newfreqitems, sizeof(ITEM_COUNTER), comp_item_freq_asc);
				for(i=0;i<num_of_newfreqitems;i++)
					pitem_suporder_map[pnewfreqitems[i].order] = i;
			}


			if(num_of_newfreqitems==1)
			{
				if(gnmax_trans_len<gndepth+1)
					gnmax_trans_len = gndepth+1;
				OutputOnePattern(pnewfreqitems[0].item, pnewfreqitems[0].support);
			}
			else if(num_of_newfreqitems>1)
			{
				if(num_of_newfreqitems<=MAX_BUCKET_SIZE)
				{
					start = clock();
					memset(gpbuckets, 0, sizeof(int)*(1<<num_of_newfreqitems));
					BucketCountAFOPT(pcurroot, pitem_suporder_map, gpbuckets);
					bucket_count(gpbuckets, num_of_newfreqitems, pnewfreqitems);
					//goTimeTracer.mdBucket_count_time += (double)(clock()-start)/CLOCKS_PER_SEC;
				}
				else 
				{
					start = clock();
					pnewheader_table = new HEADER_NODE[num_of_newfreqitems];
					//goMemTracer.IncBuffer(sizeof(HEADER_NODE)*num_of_newfreqitems);
					for(i=0;i<num_of_newfreqitems;i++)
					{
						pnewheader_table[i].item = pnewfreqitems[i].item;
						pnewheader_table[i].nsupport = pnewfreqitems[i].support;
						pnewheader_table[i].pafopt_conddb = NULL;
						pnewheader_table[i].order = i;
						pnewheader_table[i].flag = AFOPT_FLAG;
					}

					memset(gpbuckets, 0, sizeof(int)*(1<<MAX_BUCKET_SIZE));
					BuildNewTree(pcurroot, pnewheader_table, pitem_suporder_map, num_of_newfreqitems, gpbuckets); 
					//goTimeTracer.mdAFOPT_construct_time += (double)(clock()-start)/CLOCKS_PER_SEC;
					bucket_count(gpbuckets, MAX_BUCKET_SIZE, &(pnewfreqitems[num_of_newfreqitems-MAX_BUCKET_SIZE]));

					DepthAFOPTGrowth(pnewheader_table, num_of_newfreqitems, 0);
					delete []pnewheader_table;
					//goMemTracer.DecBuffer(sizeof(HEADER_NODE)*num_of_newfreqitems);
				}
			}

			start = clock();
			PushRight(pheader_table, k, nend_pos);
			//if(gndepth==1)
				//goTimeTracer.mdInitial_pushright_time += (double)(clock()-start)/CLOCKS_PER_SEC;
			//else
				//goTimeTracer.mdAFOPT_pushright_time += (double)(clock()-start)/CLOCKS_PER_SEC;
		}
		else 
		{
			delete pcurroot;
			//goMemTracer.DelOneAFOPTNode();
			pheader_table[k].pafopt_conddb = NULL;
		}
		gndepth--;
	}
	

	delete []pnewfreqitems;
	//goMemTracer.DecBuffer(num_of_freqitems*sizeof(ITEM_COUNTER));
	delete []pitem_suporder_map;
	//goMemTracer.DecBuffer(num_of_freqitems*sizeof(int));

	return;
}
Пример #7
0
//------------------------------------------------------------------------------------
//mining frequent itemsets from a conditional database represented by array structure
//------------------------------------------------------------------------------------
void CArrayMine::DepthArrayGrowth(HEADER_TABLE pheader_table, int num_of_freqitems)
{
	int	t, k;
	ITEM_COUNTER* pnewfreqitems;
	int *pitem_suporder_map;
	int num_of_newfreqitems;
	HEADER_TABLE pnewheader_table;

	clock_t start;

	gntotal_call++;

	pnewfreqitems = new ITEM_COUNTER[num_of_freqitems];
	//goMemTracer.IncBuffer(num_of_freqitems*sizeof(ITEM_COUNTER));
	pitem_suporder_map = new int[num_of_freqitems];
	//goMemTracer.IncBuffer(num_of_freqitems*sizeof(int));

	if(gnmax_pattern_len<gndepth+1)
		gnmax_pattern_len = gndepth+1;

	for(k=0;k<num_of_freqitems-BUILD_TREE_ITEM_THRESHOLD;k++)
	{
		OutputOnePattern(pheader_table[k].item, pheader_table[k].nsupport);

		if(pheader_table[k].parray_conddb != NULL)
		{
			gpheader_itemset[gndepth] = pheader_table[k].item;
			gndepth++;

			//scan the conditional database to count frequent items
			for(t=k;t<num_of_freqitems;t++)
				pitem_suporder_map[t] = 0;
			start = clock();
			CountFreqItems(pheader_table[k].parray_conddb, pitem_suporder_map);
			//goTimeTracer.mdHStruct_count_time += (double)(clock()-start)/CLOCKS_PER_SEC;
			num_of_newfreqitems = 0;
			for(t=k;t<num_of_freqitems;t++)
			{
				if(pitem_suporder_map[t]>=gnmin_sup)
				{
					pnewfreqitems[num_of_newfreqitems].item = pheader_table[t].item;
					pnewfreqitems[num_of_newfreqitems].support = pitem_suporder_map[t];
					pnewfreqitems[num_of_newfreqitems].order = t;
					num_of_newfreqitems++;
				}
				pitem_suporder_map[t] = -1;
			}
			if(num_of_newfreqitems>0)
			{
				qsort(pnewfreqitems, num_of_newfreqitems, sizeof(ITEM_COUNTER), comp_item_freq_asc);
				for(t=0;t<num_of_newfreqitems;t++)
					pitem_suporder_map[pnewfreqitems[t].order] = t;
			}


			if(num_of_newfreqitems==1)
			{
				if(gnmax_pattern_len<gndepth+1)
					gnmax_pattern_len = gndepth+1;
				OutputOnePattern(pnewfreqitems[0].item, pnewfreqitems[0].support);
			}
			else if(num_of_newfreqitems>1)
			{ 
				if(num_of_newfreqitems <= MAX_BUCKET_SIZE)
				{
					start = clock();
					memset(gpbuckets, 0, sizeof(int)*(1<<num_of_newfreqitems));
					BucketCount(pheader_table[k].parray_conddb, pitem_suporder_map, gpbuckets);
					bucket_count(gpbuckets, num_of_newfreqitems, pnewfreqitems);
					//goTimeTracer.mdBucket_count_time += (double)(clock()-start)/CLOCKS_PER_SEC;
				}
				else 
				{
					start = clock();
					pnewheader_table = new HEADER_NODE[num_of_newfreqitems];
					//goMemTracer.IncBuffer(sizeof(HEADER_NODE)*num_of_newfreqitems);

					for(t=0;t<num_of_newfreqitems;t++)
					{
						pnewheader_table[t].item = pnewfreqitems[t].item;
						pnewheader_table[t].nsupport = pnewfreqitems[t].support;
						pnewheader_table[t].pafopt_conddb = NULL;
						pnewheader_table[t].order = t;
					}
					if(num_of_newfreqitems<=BUILD_TREE_ITEM_THRESHOLD )
					{
						for(t=0;t<num_of_newfreqitems;t++)
							pnewheader_table[t].flag = AFOPT_FLAG;
					}
					else
					{
						for(t=0;t<num_of_newfreqitems-BUILD_TREE_ITEM_THRESHOLD;t++)
							pnewheader_table[t].flag = 0;
						for(t=num_of_newfreqitems-BUILD_TREE_ITEM_THRESHOLD;t<num_of_newfreqitems;t++)
							pnewheader_table[t].flag = AFOPT_FLAG;
					}

					memset(gpbuckets, 0, sizeof(int)*(1<<MAX_BUCKET_SIZE));
					BuildNewCondDB(pheader_table[k].parray_conddb, pnewheader_table, pitem_suporder_map, num_of_newfreqitems, gpbuckets); 
					//goTimeTracer.mdHStruct_construct_time += (double)(clock()-start)/CLOCKS_PER_SEC;
					bucket_count(gpbuckets, MAX_BUCKET_SIZE, &(pnewfreqitems[num_of_newfreqitems-MAX_BUCKET_SIZE]));

					if(num_of_newfreqitems<=BUILD_TREE_ITEM_THRESHOLD)
						goAFOPTMiner.DepthAFOPTGrowth(pnewheader_table, num_of_newfreqitems, 0);
					else 
					{
						DepthArrayGrowth(pnewheader_table, num_of_newfreqitems);
						goAFOPTMiner.DepthAFOPTGrowth(pnewheader_table, num_of_newfreqitems, num_of_newfreqitems-BUILD_TREE_ITEM_THRESHOLD);
					}

					delete []pnewheader_table;
					//goMemTracer.DecBuffer(num_of_newfreqitems*sizeof(HEADER_NODE));
				}
			}

			start = clock();
			PushRight(pheader_table, k, num_of_freqitems-MAX_BUCKET_SIZE);
			//if(gndepth==1)
				//goTimeTracer.mdInitial_pushright_time += (double)(clock()-start)/CLOCKS_PER_SEC;
			//else 
				//goTimeTracer.mdHStruct_pushright_time += (double)(clock()-start)/CLOCKS_PER_SEC;
			gndepth--;
		}
	}

	delete []pnewfreqitems;
	//goMemTracer.DecBuffer(num_of_freqitems*sizeof(ITEM_COUNTER));
	delete []pitem_suporder_map;
	//goMemTracer.DecBuffer(num_of_freqitems*sizeof(int));

	return;
}
Пример #8
0
void MemoryUsage::log()
{
  // std::string footprint is ~ string.capacity()
  // std::vector footprint is ~ 3 * sizeof(T*) + vector.capacity() * sizeof( T );
  // std::set footprint is ~ 3 * sizeof( void* ) + set.size() * ( sizeof(T)+3 * sizeof( void* ) );
  // std::map footprint is ~ ( sizeof(K)+sizeof( V ) + ( sizeof(void*) * 3 + 1 ) / 2 ) * map.size();

  size_t systemstate_size = Plib::systemstate.estimatedSize();
  size_t multibuffer_size = Multi::multidef_buffer.estimateSize();
  auto network_size = networkManager.estimateSize();
  auto object_sizes = objStorageManager.estimateSize();
  auto script_sizes = scriptEngineInternalManager.estimateSize();
  size_t settings_size = settingsManager.estimateSize();
  size_t state_size = stateManager.estimateSize();
  auto config_sizes = configurationbuffer.estimateSize();
  auto gamestate_size = gamestate.estimateSize();
  auto cprop_profiler_size = CPropProfiler::instance().estimateSize();

  std::vector<std::pair<std::string, size_t>> logs;
  logs.push_back( std::make_pair( "ProcessSize",      Clib::getCurrentMemoryUsage() ) );
  logs.push_back( std::make_pair( "CPProfilerSize",   cprop_profiler_size ) );
  logs.push_back( std::make_pair( "GameStateSize",    gamestate_size.misc ) );
  logs.push_back( std::make_pair( "RealmSize",        gamestate_size.realm_size ) );
  logs.push_back( std::make_pair( "SystemStateSize",  systemstate_size ) );
  logs.push_back( std::make_pair( "MultiBufferSize",  multibuffer_size ) );
  logs.push_back( std::make_pair( "SettingsSize",     settings_size ) );
  logs.push_back( std::make_pair( "StateSize",        state_size ) );
  logs.push_back( std::make_pair( "ScriptCount",      script_sizes.script_count ) );
  logs.push_back( std::make_pair( "ScriptSize",       script_sizes.script_size ) );
  logs.push_back( std::make_pair( "ScriptStoreCount", script_sizes.scriptstorage_count ) );
  logs.push_back( std::make_pair( "ScriptStoreSize",  script_sizes.scriptstorage_size ) );
  logs.push_back( std::make_pair( "ConfigCount",      config_sizes.cfg_count ) );
  logs.push_back( std::make_pair( "ConfigSize",       config_sizes.cfg_size ) );
  logs.push_back( std::make_pair( "DataStoreCount",   config_sizes.datastore_count ) );
  logs.push_back( std::make_pair( "DataStoreSize",    config_sizes.datastore_size ) );
  logs.push_back( std::make_pair( "ConfigBufferSize", config_sizes.misc ) );
  logs.push_back( std::make_pair( "AccountCount",     gamestate_size.account_count ) );
  logs.push_back( std::make_pair( "AccountSize",      gamestate_size.account_size ) );
  logs.push_back( std::make_pair( "ClientCount",      network_size.client_count ) );
  logs.push_back( std::make_pair( "ClientSize",       network_size.client_size ) );
  logs.push_back( std::make_pair( "NetworkSize",      network_size.misc ) );
  logs.push_back( std::make_pair( "ObjectStorage",    object_sizes.misc ) );

  logs.push_back( std::make_pair( "ObjItemCount",     object_sizes.obj_item_count ) );
  logs.push_back( std::make_pair( "ObjItemSize",      object_sizes.obj_item_size ) );
  logs.push_back( std::make_pair( "ObjContCount",     object_sizes.obj_cont_count ) );
  logs.push_back( std::make_pair( "ObjContSize",      object_sizes.obj_cont_size ) );
  logs.push_back( std::make_pair( "ObjCharCount",     object_sizes.obj_char_count ) );
  logs.push_back( std::make_pair( "ObjCharSize",      object_sizes.obj_char_size ) );
  logs.push_back( std::make_pair( "ObjNpcCount",      object_sizes.obj_npc_count ) );
  logs.push_back( std::make_pair( "ObjNpcSize",       object_sizes.obj_npc_size ) );
  logs.push_back( std::make_pair( "ObjWeaponCount",   object_sizes.obj_weapon_count ) );
  logs.push_back( std::make_pair( "ObjWeaponSize",    object_sizes.obj_weapon_size ) );
  logs.push_back( std::make_pair( "ObjArmorCount",    object_sizes.obj_armor_count ) );
  logs.push_back( std::make_pair( "ObjArmorSize",     object_sizes.obj_armor_size ) );
  logs.push_back( std::make_pair( "ObjMultiCount",    object_sizes.obj_multi_count ) );
  logs.push_back( std::make_pair( "ObjMultiSize",     object_sizes.obj_multi_size ) );

#ifdef DEBUG_FLYWEIGHT
  for ( size_t i = 0; i < boost_utils::debug_flyweight_queries.size(); ++i )
  {
    auto ptr = boost_utils::debug_flyweight_queries[i];
    if (ptr == nullptr)
      continue;
    auto str = std::to_string(i);
    logs.push_back( std::make_pair( "FlyWeightBucket" + str + "Count", ptr->bucket_count() ) );
    logs.push_back( std::make_pair( "FlyWeightBucket" + str + "Size",  ptr->estimateSize() ) );
  }
#endif
  bool needs_header = !Clib::FileExists( "log/memoryusage.log" );
  auto log = OPEN_FLEXLOG( "log/memoryusage.log", false );
  if ( needs_header )
  {
    fmt::Writer header;
    header << "Time";
    for (const auto& entry : logs)
      header << " ;" << entry.first;
    FLEXLOG( log ) << header.str() << "\n";
  }


  fmt::Writer line;
  line << GET_LOG_FILESTAMP;
  for (const auto& entry : logs)
    line << " ;" << entry.second;
  FLEXLOG( log ) << line.str() << "\n";

  CLOSE_FLEXLOG( log );
}