"Fossies" - the Fresh Open Source Software Archive

Member "tcpflow-1.6.1/src/be13_api/atomic_set_map.h" (19 Feb 2021, 4167 Bytes) of package /linux/misc/tcpflow-1.6.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "atomic_set_map.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.5_vs_1.5.0.

    1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
    2 
    3 /**
    4  * defines atomic_map and atomic_set
    5  *
    6  */
    7 
    8 #ifndef ATOMIC_SET_MAP_H
    9 #define ATOMIC_SET_MAP_H
   10 
   11 
   12 #include "cppmutex.h"
   13 #include <algorithm>
   14 #include <set>
   15 #include <map>
   16 
   17 #if defined(HAVE_UNORDERED_MAP)
   18 # include <unordered_map>
   19 # undef HAVE_TR1_UNORDERED_MAP           // be sure we don't use it
   20 #else
   21 # if defined(HAVE_TR1_UNORDERED_MAP)
   22 #  include <tr1/unordered_map>
   23 # endif
   24 #endif
   25 
   26 #if defined(HAVE_UNORDERED_SET)
   27 #include <unordered_set>
   28 #undef HAVE_TR1_UNORDERED_SET           // be sure we don't use it
   29 #else
   30 #if defined(HAVE_TR1_UNORDERED_SET)
   31 #include <tr1/unordered_set>
   32 #endif
   33 #endif
   34 
   35 template <class TYPE,class CTYPE> class atomic_histogram {
   36 #ifdef HAVE_UNORDERED_MAP
   37     typedef std::unordered_map<TYPE,CTYPE> hmap_t;
   38 #else
   39 #ifdef HAVE_TR1_UNORDERED_MAP
   40     typedef std::tr1::unordered_map<TYPE,CTYPE> hmap_t;
   41 #else
   42     typedef std::map<TYPE,CTYPE> hmap_t;
   43 #endif
   44 #endif
   45     hmap_t amap; // the locked atomic map
   46     mutable cppmutex M;                         // my lock
   47 public:
   48     atomic_histogram():amap(),M(){};
   49 
   50     // The callback is used to report the histogram.
   51     // The callback returns '0' if no error is encountered, '-1' if the dumping should stop
   52     typedef int (*dump_callback_t)(void *user,const TYPE &val,const CTYPE &count);
   53     // add and return the count
   54     // http://www.cplusplus.com/reference/unordered_map/unordered_map/insert/
   55     CTYPE add(const TYPE &val,const CTYPE &count){
   56         cppmutex::lock lock(M);
   57         std::pair<typename hmap_t::iterator,bool> p = amap.insert(std::make_pair(val,count));
   58 
   59         if (!p.second) {
   60             p.first->second += count;
   61         }
   62         return p.first->second;
   63     }
   64 
   65     // Dump the database to a user-provided callback.
   66     void     dump(void *user,dump_callback_t dump_cb) const{
   67         cppmutex::lock lock(M);
   68         for(typename hmap_t::const_iterator it = amap.begin();it!=amap.end();it++){
   69             int ret = (*dump_cb)(user,(*it).first,(*it).second);
   70             if(ret<0) return;
   71         }
   72     }
   73     struct ReportElement {
   74         ReportElement(TYPE aValue,uint64_t aTally):value(aValue),tally(aTally){ }
   75         TYPE value;
   76         CTYPE tally;
   77         static bool compare(const ReportElement *e1,
   78                             const ReportElement *e2) {
   79         if (e1->tally > e2->tally) return true;
   80         if (e1->tally < e2->tally) return false;
   81         return e1->value < e2->value;
   82     }
   83         virtual ~ReportElement(){};
   84     };
   85     typedef std::vector< const ReportElement *> element_vector_t;
   86 
   87     void     dump_sorted(void *user,dump_callback_t dump_cb) const {
   88         /* Create a list of new elements, sort it, then report the sorted list */
   89         element_vector_t  evect;
   90         {
   91             cppmutex::lock lock(M);
   92             for(typename hmap_t::const_iterator it = amap.begin();it!=amap.end();it++){
   93                 evect.push_back( new ReportElement((*it).first, (*it).second));
   94             }
   95         }
   96         std::sort(evect.begin(),evect.end(),ReportElement::compare);
   97         for(typename element_vector_t::const_iterator it = evect.begin();it!=evect.end();it++){
   98             int ret = (*dump_cb)(user,(*it)->value,(*it)->tally);
   99             delete *it;
  100             if(ret<0) break;
  101         }
  102 
  103     }
  104     uint64_t size_estimate() const;     // Estimate the size of the database 
  105 };
  106 
  107 template <class TYPE > class atomic_set {
  108     cppmutex M;
  109 #ifdef HAVE_UNORDERED_SET
  110     std::unordered_set<TYPE>myset;
  111 #else
  112 #ifdef HAVE_TR1_UNORDERED_SET
  113     std::tr1::unordered_set<TYPE>myset;
  114 #else
  115     std::set<TYPE>myset;
  116 #endif
  117 #endif
  118 public:
  119     atomic_set():M(),myset(){}
  120     bool contains(const TYPE &s){
  121         cppmutex::lock lock(M);
  122         return myset.find(s)!=myset.end();
  123     }
  124     void insert(const TYPE &s){
  125         cppmutex::lock lock(M);
  126         myset.insert(s);
  127     }
  128     bool check_for_presence_and_insert(const TYPE &s){
  129         cppmutex::lock lock(M);
  130         if(myset.find(s)!=myset.end()) return true; // in the set
  131         myset.insert(s);                // otherwise insert it
  132         return false;                   // and return that it wasn't
  133     }
  134 };
  135 
  136 #endif