fixes bug where priorities where lost when force-rechecking.
[libtorrent.git] / test / test_buffer.cpp
blob8f55c5aade9e3562d8a6a90430211247b39c66b4
1 /*
2 Copyright (c) 2003 - 2005, Arvid Norberg, Daniel Wallin
3 All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the distribution.
14 * Neither the name of Rasterbar Software nor the names of its
15 contributors may be used to endorse or promote products derived
16 from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 POSSIBILITY OF SUCH DAMAGE.
32 #include <cassert>
33 #include <boost/timer.hpp>
34 #include <iostream>
35 #include <vector>
36 #include <utility>
37 #include <set>
39 #include "libtorrent/buffer.hpp"
40 #include "libtorrent/chained_buffer.hpp"
41 #include "libtorrent/socket.hpp"
43 #include "test.hpp"
45 using namespace libtorrent;
48 template<class T>
49 T const& min_(T const& x, T const& y)
51 return x < y ? x : y;
54 void test_speed()
56 buffer b;
58 char data[32];
60 srand(0);
62 boost::timer t;
64 int const iterations = 5000000;
65 int const step = iterations / 20;
67 for (int i = 0; i < iterations; ++i)
69 int x = rand();
71 if (i % step == 0) std::cerr << ".";
73 std::size_t n = rand() % 32;
74 n = 32;
76 if (x % 2)
78 b.insert(data, data + n);
80 else
82 b.erase(min_(b.size(), n));
86 float t1 = t.elapsed();
87 std::cerr << "buffer elapsed: " << t.elapsed() << "\n";
89 std::vector<char> v;
91 srand(0);
92 t.restart();
94 for (int i = 0; i < iterations; ++i)
96 int x = rand();
98 if (i % step == 0) std::cerr << ".";
100 std::size_t n = rand() % 32;
101 n = 32;
103 if (x % 2)
105 v.insert(v.end(), data, data + n);
107 else
109 v.erase(v.begin(), v.begin() + min_(v.size(), n));
113 float t2 = t.elapsed();
114 std::cerr << "std::vector elapsed: " << t.elapsed() << "\n";
116 assert(t1 < t2);
120 // -- test buffer --
122 void test_buffer()
124 char data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
126 buffer b;
128 TEST_CHECK(b.size() == 0);
129 TEST_CHECK(b.capacity() == 0);
130 TEST_CHECK(b.empty());
132 b.resize(10);
133 TEST_CHECK(b.size() == 10);
134 TEST_CHECK(b.capacity() == 10);
136 std::memcpy(b.begin(), data, 10);
137 b.reserve(50);
138 TEST_CHECK(std::memcmp(b.begin(), data, 10) == 0);
139 TEST_CHECK(b.capacity() == 50);
141 b.erase(b.begin() + 6, b.end());
142 TEST_CHECK(std::memcmp(b.begin(), data, 6) == 0);
143 TEST_CHECK(b.capacity() == 50);
144 TEST_CHECK(b.size() == 6);
146 b.insert(b.begin(), data + 5, data + 10);
147 TEST_CHECK(b.capacity() == 50);
148 TEST_CHECK(b.size() == 11);
149 TEST_CHECK(std::memcmp(b.begin(), data + 5, 5) == 0);
151 b.clear();
152 TEST_CHECK(b.size() == 0);
153 TEST_CHECK(b.capacity() == 50);
155 b.insert(b.end(), data, data + 10);
156 TEST_CHECK(b.size() == 10);
157 TEST_CHECK(std::memcmp(b.begin(), data, 10) == 0);
159 b.erase(b.begin(), b.end());
160 TEST_CHECK(b.capacity() == 50);
161 TEST_CHECK(b.size() == 0);
163 buffer().swap(b);
164 TEST_CHECK(b.capacity() == 0);
168 // -- test chained buffer --
170 std::set<char*> buffer_list;
172 void free_buffer(char* m)
174 std::set<char*>::iterator i = buffer_list.find(m);
175 TEST_CHECK(i != buffer_list.end());
177 buffer_list.erase(i);
178 std::free(m);
181 char* allocate_buffer(int size)
183 char* mem = (char*)std::malloc(size);
184 buffer_list.insert(mem);
185 return mem;
188 template <class T>
189 int copy_buffers(T const& b, char* target)
191 int copied = 0;
192 for (typename T::const_iterator i = b.begin()
193 , end(b.end()); i != end; ++i)
195 memcpy(target, libtorrent::asio::buffer_cast<char const*>(*i), libtorrent::asio::buffer_size(*i));
196 target += libtorrent::asio::buffer_size(*i);
197 copied += libtorrent::asio::buffer_size(*i);
199 return copied;
202 bool compare_chained_buffer(chained_buffer& b, char const* mem, int size)
204 if (size == 0) return true;
205 std::vector<char> flat(size);
206 std::list<libtorrent::asio::const_buffer> const& iovec2 = b.build_iovec(size);
207 int copied = copy_buffers(iovec2, &flat[0]);
208 TEST_CHECK(copied == size);
209 return std::memcmp(&flat[0], mem, size) == 0;
212 void test_chained_buffer()
214 char data[] = "foobar";
216 chained_buffer b;
218 TEST_CHECK(b.empty());
219 TEST_CHECK(b.capacity() == 0);
220 TEST_CHECK(b.size() == 0);
221 TEST_CHECK(b.space_in_last_buffer() == 0);
222 TEST_CHECK(buffer_list.empty());
224 char* b1 = allocate_buffer(512);
225 std::memcpy(b1, data, 6);
226 b.append_buffer(b1, 512, 6, (void(*)(char*))&free_buffer);
227 TEST_CHECK(buffer_list.size() == 1);
229 TEST_CHECK(b.capacity() == 512);
230 TEST_CHECK(b.size() == 6);
231 TEST_CHECK(!b.empty());
232 TEST_CHECK(b.space_in_last_buffer() == 512 - 6);
234 b.pop_front(3);
236 TEST_CHECK(b.capacity() == 512);
237 TEST_CHECK(b.size() == 3);
238 TEST_CHECK(!b.empty());
239 TEST_CHECK(b.space_in_last_buffer() == 512 - 6);
241 bool ret = b.append(data, 6);
243 TEST_CHECK(ret == true);
244 TEST_CHECK(b.capacity() == 512);
245 TEST_CHECK(b.size() == 9);
246 TEST_CHECK(!b.empty());
247 TEST_CHECK(b.space_in_last_buffer() == 512 - 12);
249 ret = b.append(data, 1024);
251 TEST_CHECK(ret == false);
253 char* b2 = allocate_buffer(512);
254 std::memcpy(b2, data, 6);
255 b.append_buffer(b2, 512, 6, (void(*)(char*))&free_buffer);
256 TEST_CHECK(buffer_list.size() == 2);
258 char* b3 = allocate_buffer(512);
259 std::memcpy(b3, data, 6);
260 b.append_buffer(b3, 512, 6, (void(*)(char*))&free_buffer);
261 TEST_CHECK(buffer_list.size() == 3);
263 TEST_CHECK(b.capacity() == 512 * 3);
264 TEST_CHECK(b.size() == 21);
265 TEST_CHECK(!b.empty());
266 TEST_CHECK(b.space_in_last_buffer() == 512 - 6);
268 TEST_CHECK(compare_chained_buffer(b, "barfoobar", 9));
270 for (int i = 1; i < 21; ++i)
271 TEST_CHECK(compare_chained_buffer(b, "barfoobarfoobarfoobar", i));
273 b.pop_front(5 + 6);
275 TEST_CHECK(buffer_list.size() == 2);
276 TEST_CHECK(b.capacity() == 512 * 2);
277 TEST_CHECK(b.size() == 10);
278 TEST_CHECK(!b.empty());
279 TEST_CHECK(b.space_in_last_buffer() == 512 - 6);
281 char const* str = "obarfooba";
282 TEST_CHECK(compare_chained_buffer(b, str, 9));
284 for (int i = 0; i < 9; ++i)
286 b.pop_front(1);
287 ++str;
288 TEST_CHECK(compare_chained_buffer(b, str, 8 - i));
289 TEST_CHECK(b.size() == 9 - i);
292 char* b4 = allocate_buffer(20);
293 std::memcpy(b4, data, 6);
294 std::memcpy(b4 + 6, data, 6);
295 b.append_buffer(b4, 20, 12, (void(*)(char*))&free_buffer);
296 TEST_CHECK(b.space_in_last_buffer() == 8);
298 ret = b.append(data, 6);
299 TEST_CHECK(ret == true);
300 TEST_CHECK(b.space_in_last_buffer() == 2);
301 std::cout << b.space_in_last_buffer() << std::endl;
302 ret = b.append(data, 2);
303 TEST_CHECK(ret == true);
304 TEST_CHECK(b.space_in_last_buffer() == 0);
305 std::cout << b.space_in_last_buffer() << std::endl;
307 char* b5 = allocate_buffer(20);
308 std::memcpy(b4, data, 6);
309 b.append_buffer(b5, 20, 6, (void(*)(char*))&free_buffer);
311 b.pop_front(22);
312 TEST_CHECK(b.size() == 5);
314 TEST_CHECK(buffer_list.empty());
317 int test_main()
319 test_buffer();
320 test_chained_buffer();
321 return 0;