BoundedHash.h
Go to the documentation of this file.
00001 /*------------------------------------------------------------------------
00002  *---------------------           WMPSNIFFER          --------------------
00003  *------------------------------------------------------------------------
00004  *                                                         V7.0B  11/05/10
00005  *
00006  *
00007  *  File: BoundedHash.h
00008  *  Authors: Danilo Tardioli
00009  *  ----------------------------------------------------------------------
00010  *  Copyright (C) 2000-2012, Universidad de Zaragoza, SPAIN
00011  *
00012  *  Contact Addresses: Danilo Tardioli                   dantard@unizar.es
00013  *
00014  *  RT-WMP is free software; you can  redistribute it and/or  modify it
00015  *  under the terms of the GNU General Public License  as published by the
00016  *  Free Software Foundation;  either  version 2, or (at  your option) any
00017  *  later version.
00018  *
00019  *  RT-WMP  is distributed  in the  hope  that  it will be   useful, but
00020  *  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
00021  *  MERCHANTABILITY  or  FITNESS FOR A  PARTICULAR PURPOSE.    See the GNU
00022  *  General Public License for more details.
00023  *
00024  *  You should have received  a  copy of  the  GNU General Public  License
00025  *  distributed with RT-WMP;  see file COPYING.   If not,  write to the
00026  *  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
00027  *  02111-1307, USA.
00028  *
00029  *  As a  special exception, if you  link this  unit  with other  files to
00030  *  produce an   executable,   this unit  does  not  by  itself cause  the
00031  *  resulting executable to be covered by the  GNU General Public License.
00032  *  This exception does  not however invalidate  any other reasons why the
00033  *  executable file might be covered by the GNU Public License.
00034  *
00035  *----------------------------------------------------------------------*/
00036 #ifndef BOUNDEDHASH_H_
00037 #define BOUNDEDHASH_H_
00038 
00039 #include <ext/hash_map>
00040 #include <iostream>
00041 #include <vector>
00042 #include <string>
00043 #include <map>
00044 #include <pthread.h>
00045 #include <semaphore.h>
00046 #include <cassert>
00047 using namespace std;
00048 using __gnu_cxx::hash_map;
00049 
00050 
00051 
00052 template <class S, class T, class R> class BoundedHash {
00053         typedef typename multimap<S,S>::iterator mmit;
00054 private:
00055 
00056         struct bh_ts_key{
00057                 S first, second, ds;
00058                 R sort_key;
00059         };
00060 
00061         static bool sort_fun(bh_ts_key i, bh_ts_key j) {
00062                 if (i.sort_key < 0 || j.sort_key < 0) assert(0);
00063 
00064                 return (i.sort_key <= j.sort_key);
00065         }
00066 
00067         pthread_mutex_t mtxs;
00068         sem_t sem;
00069         hash_map<S,T> hm;
00070         multimap<S,S> mm;
00071         int size,buffer;
00072         std::vector<bh_ts_key> v;
00073         bool strict;
00074 
00075         bool erase(int vector_idx){
00076                 bh_ts_key elem = v.at(vector_idx);
00077                 S key = elem.first;
00078                 S key2 = elem.second;
00079                 //cout << "kill elem first key : "<< elem.first << "\n";
00080                 //cout << "kill elem sec   key2: "<< elem.second << "\n";
00081                 v.erase(v.begin()+vector_idx);
00082                 hm.erase(key);
00083                 std::pair< mmit, mmit > it;
00084                 bool deleted=true;
00085                 while (deleted){
00086                         deleted=false;
00087                         it = mm.equal_range(key2);
00088                         for (mmit it2 = it.first; it2 != it.second;++it2) {
00089                                 if (it2->second == key) {
00090                                         mm.erase(it2);
00091                                         deleted=true;
00092                                         break;
00093                                 }
00094                         }
00095                 }
00096                 return true;
00097         }
00098 public:
00099 
00100         BoundedHash(int size, int buffer){
00101                 this->size=size;
00102                 this->strict = false;
00103                 pthread_mutex_init(&mtxs,0);
00104                 sem_init(&sem,0,0);
00105         }
00106 
00107         BoundedHash(){
00108                 this->size=100;
00109                 this->buffer=50;
00110                 this->strict = false;
00111                 pthread_mutex_init(&mtxs,0);
00112                 sem_init(&sem,0,0);
00113         }
00114         void setStrict(bool _strict){
00115                 strict = _strict;
00116         }
00117         int getSize(){
00118                 //cout << "hm:" << hm.size() << " mm: " << mm.size();
00119                 return v.size();
00120         }
00121 
00122         bool setBufferSize(int size){
00123                 this->buffer=size;
00124                 return true;
00125         }
00126 
00127         bool setSize(int size){
00128                 if (v.size()<size){
00129                         this->size=size;
00130                         return true;
00131                 }else{
00132                         return false;
00133                 }
00134         }
00135 
00136         virtual ~BoundedHash(){}
00137 
00138         void lock(){
00139                 pthread_mutex_lock(&mtxs);
00140         }
00141         void unlock(){
00142                 pthread_mutex_unlock(&mtxs);
00143         }
00144 
00145         void drain(){
00146                 int nelem=0;
00147                 if (v.size() > buffer){
00148                         nelem = buffer;
00149                 } else{
00150                         nelem = v.size();
00151                 }
00152                 for (int i = 0 ; i < nelem; i++){
00153                         sem_post(&sem);
00154                 }
00155         }
00156 
00157         T& insert(S key, S key2, R sort_key){
00158                 bool present=false;
00159                 for (int i=0; i<v.size(); i++){
00160                         present |= (v.at(i).first==key);
00161                 }
00162                 bh_ts_key p;
00163                 p.first=key;
00164                 p.second=key2;
00165                 p.sort_key=sort_key;
00166                 if (not present){
00167                         mm.insert(pair<S,S>(key2, key));
00168                         v.push_back(p);
00169                         //cout << "Inserting elem : "<< v.size() << "\n";
00170                         if (v.size() == size && !strict){
00171                                 erase(0);
00172                         }else{
00173                                 if (v.size()>buffer) sem_post(&sem);
00174                         }
00175                 }
00176                 /* DEBUG if (v.size()>10){
00177                         for (int i=0;i<10;i++){
00178                                 fprintf(stderr,"Pos#%d Key1:%d key2:%d\n",i,v.at(i).first,v.at(i).second);
00179                         }
00180                 }*/
00181                 return hm[key];
00182         }
00183 
00184         void sort(){
00185                 std::sort(v.begin(),v.end(),sort_fun);
00186         }
00187 
00188         T& get(S key){
00189                 return hm[key];
00190         }
00191 
00192         S getKey(S key2, int idx=0){
00193                 pthread_mutex_lock(&mtxs);
00194                 std::pair< mmit, mmit > it= mm.equal_range(key2);
00195                 mmit it2 = it.first;
00196                 pthread_mutex_unlock(&mtxs);
00197                 advance(it2,idx);
00198                 return it2->second;
00199         }
00200 
00201         int countk2(S key2){
00202                 pthread_mutex_lock(&mtxs);
00203                 int c =mm.count(key2);
00204                 pthread_mutex_unlock(&mtxs);
00205                 return c;
00206         }
00207 
00208         T pop(){
00209                 sem_wait(&sem);
00210                 pthread_mutex_lock(&mtxs);
00211                 //std::sort(v.begin(),v.end(),sort_fun);
00212                 bh_ts_key elem = v.at(0);
00213                 int key = elem.first;
00214                 T t = hm[key];
00215                 erase(0);
00216                 pthread_mutex_unlock(&mtxs);
00217                 return t;
00218         }
00219 
00220         T pop(int key){
00221                 pthread_mutex_lock(&mtxs);
00222                 int idx=-1;
00223                 for (int i=0; i<v.size(); i++){
00224                         if (key==v.at(i).first){
00225                                 idx=i;
00226                         }
00227                 }
00228                 T t = hm[key];
00229                 if (idx >= 0) erase(idx);
00230 
00231                 pthread_mutex_unlock(&mtxs);
00232                 return t;
00233         }
00234 
00235         bool find(S key){
00236                 bool present=false;
00237                 for (int i=0; i<v.size(); i++){
00238                         present |= (v.at(i).first==key);
00239                 }
00240                 return present;
00241         }
00242 
00243         void sleep(){
00244                 if (v.size()>this->size){
00245                         usleep(v.size()-this->size);
00246                 }
00247         }
00248 
00249         void clear(){
00250                 int nSignals = (v.size()-buffer)>0?(v.size()-buffer):0;
00251                 for (int i = 0 ; i <nSignals  ; i++){
00252                         pop();
00253                 }
00254                 v.clear();
00255                 hm.clear();
00256                 mm.clear();
00257         }
00258         bool blocked(){
00259                 return (not(v.size()>buffer));
00260         }
00261         void signal(){
00262                 sem_post(&sem);
00263         }
00264 };
00265 
00266 #endif /* BOUNDEDHASH_H_ */


ros_rt_wmp_sniffer
Author(s): Danilo Tardioli, dantard@unizar.es
autogenerated on Mon Oct 6 2014 08:27:57