tcpflow  1.6.1
About: tcpflow is a TCP/IP packet demultiplexer that captures data transmitted as part of TCP connections (flows), and stores the data in a way that is convenient for protocol analysis and debugging.
  Fossies Dox: tcpflow-1.6.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

atomic_set_map.h
Go to the documentation of this file.
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:
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 {
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:
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
void dump(void *user, dump_callback_t dump_cb) const
uint64_t size_estimate() const
std::vector< const ReportElement * > element_vector_t
CTYPE add(const TYPE &val, const CTYPE &count)
std::map< TYPE, CTYPE > hmap_t
int(* dump_callback_t)(void *user, const TYPE &val, const CTYPE &count)
void dump_sorted(void *user, dump_callback_t dump_cb) const
std::set< TYPE > myset
void insert(const TYPE &s)
bool contains(const TYPE &s)
cppmutex M
bool check_for_presence_and_insert(const TYPE &s)
static bool compare(const ReportElement *e1, const ReportElement *e2)
ReportElement(TYPE aValue, uint64_t aTally)