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; } } } }
/** * 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()) { }
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); }
size_t constrain_hash (const T& key) { return __constrain_hash(t_hash(key), bucket_count()); }
//--------------------------------------------- //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)); }
//----------------------------------------------------------------------------------- //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; }
//------------------------------------------------------------------------------------ //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; }
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 ); }