Marine Library  1.0
C++ library for Linux Networking Development
fd_data_map.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Zhao DAI <daidodo@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or any
7  * later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see accompanying file LICENSE.txt
16  * or <http://www.gnu.org/licenses/>.
17  */
18 
25 #ifndef DOZERG_FD_DATA_MAP_H_20130228
26 #define DOZERG_FD_DATA_MAP_H_20130228
27 
28 #include <vector>
29 #include <cassert>
30 #include "mutex.hh"
31 #include "shared_ptr.hh"
32 
33 NS_SERVER_BEGIN
34 
47 template<class T, class Container = std::vector<T> >
48 struct CFdMap
49 {
50  typedef Container container_type;
51  typedef T value_type;
52  typedef T & reference;
53  typedef const T & const_reference;
60  explicit CFdMap(size_t capacity = 100){map_.reserve(capacity);}
65  size_t capacity() const{return map_.capacity();}
70  void capacity(size_t sz){map_.reserve(sz);}
76  reference operator [](int fd){
77  assert(fd >= 0);
78  if(size_t(fd) >= map_.size())
79  map_.resize(fd + 1);
80  return map_[fd];
81  }
87  const_reference operator [](int fd) const{
88  //use value_type() to fix compile error for POD
89  static const value_type kDef = value_type();
90  if(fd >= 0 && size_t(fd) < map_.size())
91  return map_[fd];
92  return kDef;
93  }
97  void clear(){map_.clear();}
98 private:
99  container_type map_;
100 };
101 
120 template<class T, class LockT = CSpinLock>
122 {
123 public:
124  typedef T value_type;
126 private:
127  typedef CFdMap<pointer> __Map;
128  typedef LockT lock_type;
130 public:
137  explicit CFdDataMap(size_t capacity = 100)
138  : map_(capacity)
139  , sz_(0)
140  {}
145  size_t size() const{return sz_;}
150  size_t capacity() const{
151  guard_type g(lock_);
152  return map_.capacity();
153  }
158  void capacity(size_t c){
159  guard_type g(lock_);
160  map_.capacity(c);
161  }
168  void setData(int fd, const pointer & data, pointer * old = NULL){
169  if(fd < 0)
170  return;
171  guard_type g(lock_);
172  setAux(fd, data, old);
173  }
179  pointer getData(int fd) const{
180  if(fd < 0)
181  return pointer();
182  guard_type g(lock_);
183  return map_[fd];
184  }
190  void getData(int fd, pointer * data) const{
191  if(NULL == data || fd < 0)
192  return;
193  guard_type g(lock_);
194  *data = map_[fd];
195  }
214  template<class ForwardIter, class OutputIter>
215  void getData(ForwardIter first, ForwardIter last, OutputIter dstFirst) const{
216  guard_type g(lock_);
217  for(int fd = -1;first != last;++first, ++dstFirst){
218  fd = *first;
219  if(fd >= 0)
220  *dstFirst = map_[fd];
221  }
222  }
229  void clearData(int fd, pointer * old = NULL){
230  if(fd < 0)
231  return;
232  guard_type g(lock_);
233  setAux(fd, pointer(), old);
234  }
240  template<class ForwardIter>
241  void clearData(ForwardIter first, ForwardIter last){
242  guard_type g(lock_);
243  for(int fd = -1;first != last;++first){
244  fd = *first;
245  if(fd >= 0)
246  setAux(fd, pointer(), NULL);
247  }
248  }
256  template<class ForwardIter, class OutputIter>
257  void clearData(ForwardIter first, ForwardIter last, OutputIter dstFirst){
258  guard_type g(lock_);
259  for(int fd = -1;first != last;++first, ++dstFirst){
260  fd = *first;
261  if(fd >= 0)
262  setAux(fd, pointer(), &*dstFirst);
263  }
264  }
268  void clear(){
269  guard_type g(lock_);
270  map_.clear();
271  sz_ = 0;
272  }
273 private:
274  //set *old = map_[fd], then set map_[fd] = data
275  //Note: old and &data may be equal
276  void setAux(int fd, const pointer & data, pointer * old){
277  assert(fd >= 0);
278  if(fd < int(map_.capacity())){
279  pointer & cur = map_[fd];
280  sz_ += (data ? 1 : 0) - (cur ? 1 : 0);
281  if(NULL != old)
282  old->swap(cur);
283  if(&data != old)
284  cur = data;
285  }else{
286  if(data){
287  map_[fd] = data;
288  ++sz_;
289  }
290  if(NULL != old)
291  old->reset();
292  }
293  }
294  //fields:
295  __Map map_;
296  lock_type lock_;
297  volatile size_t sz_;
298 };
299 
300 NS_SERVER_END
301 
302 #endif
void getData(ForwardIter first, ForwardIter last, OutputIter dstFirst) const
Get values for some file descriptors.
Definition: fd_data_map.hh:215
void capacity(size_t sz)
Set current capacity.
Definition: fd_data_map.hh:70
size_t capacity() const
Get current capacity.
Definition: fd_data_map.hh:150
CFdMap(size_t capacity=100)
Initialize this object.
Definition: fd_data_map.hh:60
void clear()
Clear all key/value pairs.
Definition: fd_data_map.hh:97
void clearData(int fd, pointer *old=NULL)
Remove value for an fd.
Definition: fd_data_map.hh:229
pointer getData(int fd) const
Get value for an fd.
Definition: fd_data_map.hh:179
void clearData(ForwardIter first, ForwardIter last, OutputIter dstFirst)
Remove values for some file descriptors.
Definition: fd_data_map.hh:257
Thread-safe hash table for fd (file descriptor) related data.
Definition: fd_data_map.hh:121
void setData(int fd, const pointer &data, pointer *old=NULL)
Set value for an fd.
Definition: fd_data_map.hh:168
CFdDataMap(size_t capacity=100)
Initialize this object.
Definition: fd_data_map.hh:137
void clearData(ForwardIter first, ForwardIter last)
Remove values for some file descriptors.
Definition: fd_data_map.hh:241
Definition: shared_ptr.hh:24
void getData(int fd, pointer *data) const
Get value for an fd.
Definition: fd_data_map.hh:190
size_t size() const
Get number of key/value pairs.
Definition: fd_data_map.hh:145
A hash table for fd (file descriptor) related data.
Definition: fd_data_map.hh:48
Definition: mutex.hh:430
void clear()
Clear all key/value pairs.
Definition: fd_data_map.hh:268
void capacity(size_t c)
Set current capacity.
Definition: fd_data_map.hh:158
reference operator[](int fd)
Get value for an fd.
Definition: fd_data_map.hh:76
size_t capacity() const
Get current capacity.
Definition: fd_data_map.hh:65