IBR-DTNSuite  0.10
BundleSet.cpp
Go to the documentation of this file.
1 /*
2  * BundleSet.cpp
3  *
4  * Created on: 18.12.2012
5  * Author: morgenro
6  */
7 
9 #include <vector>
10 
11 namespace dtn
12 {
13  namespace data
14  {
16  { }
17 
19  : _bf(bf_size * 8), _listener(listener), _consistent(true)
20  {
21  }
22 
24  {
25  }
26 
27  void BundleSet::add(const dtn::data::MetaBundle &bundle) throw ()
28  {
29  // insert bundle id to the private list
30  pair<std::set<dtn::data::MetaBundle>::iterator,bool> ret = _bundles.insert(bundle);
31 
32  ExpiringBundle exb(*ret.first);
33  _expire.insert(exb);
34 
35  // add bundle to the bloomfilter
36  _bf.insert(bundle.toString());
37  }
38 
39  void BundleSet::clear() throw ()
40  {
41  _consistent = true;
42  _bundles.clear();
43  _expire.clear();
44  _bf.clear();
45  }
46 
47  bool BundleSet::has(const dtn::data::BundleID &bundle) const throw ()
48  {
49  // check bloom-filter first
50  if (_bf.contains(bundle.toString())) {
51  // Return true if the bloom-filter is not consistent with
52  // the bundles set. This happen if the BundleSet gets deserialized.
53  if (!_consistent) return true;
54 
55  std::set<dtn::data::MetaBundle>::iterator iter = _bundles.find(dtn::data::MetaBundle::mockUp(bundle));
56  return (iter != _bundles.end());
57  }
58 
59  return false;
60  }
61 
62  Size BundleSet::size() const throw ()
63  {
64  return _bundles.size();
65  }
66 
67  void BundleSet::expire(const Timestamp timestamp) throw ()
68  {
69  bool commit = false;
70 
71  // we can not expire bundles if we have no idea of time
72  if (timestamp == 0) return;
73 
74  std::set<ExpiringBundle>::iterator iter = _expire.begin();
75 
76  while (iter != _expire.end())
77  {
78  const ExpiringBundle &b = (*iter);
79 
80  if ( b.bundle.expiretime >= timestamp ) break;
81 
82  // raise expired event
83  if (_listener != NULL)
84  _listener->eventBundleExpired( b.bundle );
85 
86  // remove this item in public list
87  _bundles.erase( b.bundle );
88 
89  // remove this item in private list
90  _expire.erase( iter++ );
91 
92  // set commit to true (triggers bloom-filter rebuild)
93  commit = true;
94  }
95 
96  if (commit)
97  {
98  // rebuild the bloom-filter
99  _bf.clear();
100  for (std::set<dtn::data::MetaBundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
101  {
102  _bf.insert( (*iter).toString() );
103  }
104  }
105  }
106 
108  {
109  return _bf;
110  }
111 
112  std::set<dtn::data::MetaBundle> BundleSet::getNotIn(ibrcommon::BloomFilter &filter) const throw ()
113  {
114  std::set<dtn::data::MetaBundle> ret;
115 
116 // // if the lists are equal return an empty list
117 // if (filter == _bf) return ret;
118 
119  // iterate through all items to find the differences
120  for (std::set<dtn::data::MetaBundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
121  {
122  if (!filter.contains( (*iter).toString() ) )
123  {
124  ret.insert( (*iter) );
125  }
126  }
127 
128  return ret;
129  }
130 
131  BundleSet::ExpiringBundle::ExpiringBundle(const MetaBundle &b)
132  : bundle(b)
133  { }
134 
135  BundleSet::ExpiringBundle::~ExpiringBundle()
136  { }
137 
138  bool BundleSet::ExpiringBundle::operator!=(const ExpiringBundle& other) const
139  {
140  return !(other == *this);
141  }
142 
143  bool BundleSet::ExpiringBundle::operator==(const ExpiringBundle& other) const
144  {
145  return (other.bundle == this->bundle);
146  }
147 
148  bool BundleSet::ExpiringBundle::operator<(const ExpiringBundle& other) const
149  {
150  if (bundle.expiretime < other.bundle.expiretime) return true;
151  if (bundle.expiretime != other.bundle.expiretime) return false;
152 
153  if (bundle < other.bundle) return true;
154 
155  return false;
156  }
157 
158  bool BundleSet::ExpiringBundle::operator>(const ExpiringBundle& other) const
159  {
160  return !(((*this) < other) || ((*this) == other));
161  }
162 
163  Length BundleSet::getLength() const throw ()
164  {
165  return dtn::data::Number(_bf.size()).getLength() + _bf.size();
166  }
167 
168  std::ostream &operator<<(std::ostream &stream, const BundleSet &obj)
169  {
170  dtn::data::Number size(obj._bf.size());
171  stream << size;
172 
173  const char *data = reinterpret_cast<const char*>(obj._bf.table());
174  stream.write(data, obj._bf.size());
175 
176  return stream;
177  }
178 
179  std::istream &operator>>(std::istream &stream, BundleSet &obj)
180  {
181  dtn::data::Number count;
182  stream >> count;
183 
184  std::vector<char> buffer(count.get<size_t>());
185 
186  stream.read(&buffer[0], buffer.size());
187 
188  obj.clear();
189  obj._bf.load((unsigned char*)&buffer[0], buffer.size());
190 
191  // set the set to in-consistent mode
192  obj._consistent = false;
193 
194  return stream;
195  }
196  } /* namespace data */
197 } /* namespace dtn */