Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
00080
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
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
00170 if (v.size() == size && !strict){
00171 erase(0);
00172 }else{
00173 if (v.size()>buffer) sem_post(&sem);
00174 }
00175 }
00176
00177
00178
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
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