blob: 60694a3bdb0ead40182681ab78653c0b9fc9db42 [file] [log] [blame]
Howard Hinnant27e0e772011-09-14 18:33:51 +00001//===-------------------------- debug.cpp ---------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnant6148a9b2013-08-23 20:10:18 +000010#define _LIBCPP_DEBUG 1
Howard Hinnanta47c6d52011-09-16 17:29:17 +000011#include "__config"
Howard Hinnant27e0e772011-09-14 18:33:51 +000012#include "__debug"
13#include "functional"
14#include "algorithm"
15#include "__hash_table"
16#include "mutex"
17
18_LIBCPP_BEGIN_NAMESPACE_STD
19
Howard Hinnant8331b762013-03-06 23:30:19 +000020_LIBCPP_FUNC_VIS
Howard Hinnant27e0e772011-09-14 18:33:51 +000021__libcpp_db*
22__get_db()
23{
24 static __libcpp_db db;
25 return &db;
Howard Hinnant434ebf72012-12-27 18:46:00 +000026}
Howard Hinnant27e0e772011-09-14 18:33:51 +000027
Howard Hinnant8331b762013-03-06 23:30:19 +000028_LIBCPP_FUNC_VIS
Howard Hinnant27e0e772011-09-14 18:33:51 +000029const __libcpp_db*
30__get_const_db()
31{
32 return __get_db();
33}
34
35namespace
36{
37
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +000038#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +000039typedef mutex mutex_type;
Howard Hinnant27e0e772011-09-14 18:33:51 +000040typedef lock_guard<mutex_type> WLock;
41typedef lock_guard<mutex_type> RLock;
42
43mutex_type&
44mut()
45{
46 static mutex_type m;
47 return m;
48}
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +000049#endif // !_LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +000050
51} // unnamed namespace
52
53__i_node::~__i_node()
54{
55 if (__next_)
56 {
57 __next_->~__i_node();
58 free(__next_);
59 }
60}
61
62__c_node::~__c_node()
63{
64 free(beg_);
65 if (__next_)
66 {
67 __next_->~__c_node();
68 free(__next_);
69 }
70}
71
72__libcpp_db::__libcpp_db()
73 : __cbeg_(nullptr),
74 __cend_(nullptr),
75 __csz_(0),
76 __ibeg_(nullptr),
77 __iend_(nullptr),
78 __isz_(0)
79{
80}
81
82__libcpp_db::~__libcpp_db()
83{
84 if (__cbeg_)
85 {
86 for (__c_node** p = __cbeg_; p != __cend_; ++p)
87 {
88 if (*p != nullptr)
89 {
90 (*p)->~__c_node();
91 free(*p);
92 }
93 }
94 free(__cbeg_);
95 }
96 if (__ibeg_)
97 {
98 for (__i_node** p = __ibeg_; p != __iend_; ++p)
99 {
100 if (*p != nullptr)
101 {
102 (*p)->~__i_node();
103 free(*p);
104 }
105 }
106 free(__ibeg_);
107 }
108}
109
110void*
111__libcpp_db::__find_c_from_i(void* __i) const
112{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000113#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000114 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000115#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000116 __i_node* i = __find_iterator(__i);
Howard Hinnant17e485c2013-04-05 17:58:52 +0000117 _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
Howard Hinnantc90aa632011-09-16 19:52:23 +0000118 return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000119}
120
121void
122__libcpp_db::__insert_ic(void* __i, const void* __c)
123{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000124#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000125 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000126#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000127 if (__cbeg_ == __cend_)
128 return;
Howard Hinnant28b24882011-12-01 20:21:04 +0000129 size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000130 __c_node* c = __cbeg_[hc];
Howard Hinnant8ea98242013-08-23 17:37:05 +0000131 if (c == nullptr)
132 return;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000133 while (c->__c_ != __c)
134 {
135 c = c->__next_;
Howard Hinnant8ea98242013-08-23 17:37:05 +0000136 if (c == nullptr)
137 return;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000138 }
Howard Hinnant8ea98242013-08-23 17:37:05 +0000139 __i_node* i = __insert_iterator(__i);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000140 c->__add(i);
141 i->__c_ = c;
142}
143
144__c_node*
145__libcpp_db::__insert_c(void* __c)
146{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000147#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000148 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000149#endif
Howard Hinnant28b24882011-12-01 20:21:04 +0000150 if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
Howard Hinnant27e0e772011-09-14 18:33:51 +0000151 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000152 size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000153 __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(void*)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000154 if (cbeg == nullptr)
Howard Hinnantc2834e62012-08-24 22:15:12 +0000155#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000156 throw bad_alloc();
Howard Hinnantc2834e62012-08-24 22:15:12 +0000157#else
158 abort();
159#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000160 for (__c_node** p = __cbeg_; p != __cend_; ++p)
161 {
162 __c_node* q = *p;
163 while (q != nullptr)
164 {
165 size_t h = hash<void*>()(q->__c_) % nc;
166 __c_node* r = q->__next_;
167 q->__next_ = cbeg[h];
168 cbeg[h] = q;
169 q = r;
170 }
171 }
172 free(__cbeg_);
173 __cbeg_ = cbeg;
174 __cend_ = __cbeg_ + nc;
175 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000176 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000177 __c_node* p = __cbeg_[hc];
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000178 __c_node* r = __cbeg_[hc] =
179 static_cast<__c_node*>(malloc(sizeof(__c_node)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000180 if (__cbeg_[hc] == nullptr)
Howard Hinnantc2834e62012-08-24 22:15:12 +0000181#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000182 throw bad_alloc();
Howard Hinnantc2834e62012-08-24 22:15:12 +0000183#else
184 abort();
185#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000186 r->__c_ = __c;
187 r->__next_ = p;
188 ++__csz_;
189 return r;
190}
191
192void
193__libcpp_db::__erase_i(void* __i)
194{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000195#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000196 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000197#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000198 if (__ibeg_ != __iend_)
199 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000200 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000201 __i_node* p = __ibeg_[hi];
202 if (p != nullptr)
203 {
204 __i_node* q = nullptr;
205 while (p->__i_ != __i)
206 {
207 q = p;
208 p = p->__next_;
209 if (p == nullptr)
210 return;
211 }
212 if (q == nullptr)
213 __ibeg_[hi] = p->__next_;
214 else
215 q->__next_ = p->__next_;
216 __c_node* c = p->__c_;
217 free(p);
218 --__isz_;
219 if (c != nullptr)
220 c->__remove(p);
221 }
222 }
223}
224
225void
226__libcpp_db::__invalidate_all(void* __c)
227{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000228#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000229 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000230#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000231 if (__cend_ != __cbeg_)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000232 {
Howard Hinnant8ea98242013-08-23 17:37:05 +0000233 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
234 __c_node* p = __cbeg_[hc];
235 if (p == nullptr)
236 return;
237 while (p->__c_ != __c)
238 {
239 p = p->__next_;
240 if (p == nullptr)
241 return;
242 }
243 while (p->end_ != p->beg_)
244 {
245 --p->end_;
246 (*p->end_)->__c_ = nullptr;
247 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000248 }
249}
250
251__c_node*
252__libcpp_db::__find_c_and_lock(void* __c) const
253{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000254#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000255 mut().lock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000256#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000257 if (__cend_ == __cbeg_)
258 {
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000259#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant8ea98242013-08-23 17:37:05 +0000260 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000261#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000262 return nullptr;
263 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000264 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000265 __c_node* p = __cbeg_[hc];
Howard Hinnant8ea98242013-08-23 17:37:05 +0000266 if (p == nullptr)
267 {
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000268#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant8ea98242013-08-23 17:37:05 +0000269 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000270#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000271 return nullptr;
272 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000273 while (p->__c_ != __c)
274 {
275 p = p->__next_;
Howard Hinnant8ea98242013-08-23 17:37:05 +0000276 if (p == nullptr)
277 {
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000278#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant8ea98242013-08-23 17:37:05 +0000279 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000280#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000281 return nullptr;
282 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000283 }
284 return p;
285}
286
Howard Hinnantb399c602011-09-27 23:55:03 +0000287__c_node*
288__libcpp_db::__find_c(void* __c) const
289{
Howard Hinnant28b24882011-12-01 20:21:04 +0000290 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnantb399c602011-09-27 23:55:03 +0000291 __c_node* p = __cbeg_[hc];
292 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
293 while (p->__c_ != __c)
294 {
295 p = p->__next_;
296 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
297 }
298 return p;
299}
300
Howard Hinnant27e0e772011-09-14 18:33:51 +0000301void
302__libcpp_db::unlock() const
303{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000304#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000305 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000306#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000307}
308
309void
310__libcpp_db::__erase_c(void* __c)
311{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000312#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000313 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000314#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000315 if (__cend_ != __cbeg_)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000316 {
Howard Hinnant8ea98242013-08-23 17:37:05 +0000317 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
318 __c_node* p = __cbeg_[hc];
319 if (p == nullptr)
320 return;
321 __c_node* q = nullptr;
322 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
323 while (p->__c_ != __c)
324 {
325 q = p;
326 p = p->__next_;
327 if (p == nullptr)
328 return;
329 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
330 }
331 if (q == nullptr)
332 __cbeg_[hc] = p->__next_;
333 else
334 q->__next_ = p->__next_;
335 while (p->end_ != p->beg_)
336 {
337 --p->end_;
338 (*p->end_)->__c_ = nullptr;
339 }
340 free(p->beg_);
341 free(p);
342 --__csz_;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000343 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000344}
345
346void
347__libcpp_db::__iterator_copy(void* __i, const void* __i0)
348{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000349#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000350 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000351#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000352 __i_node* i = __find_iterator(__i);
353 __i_node* i0 = __find_iterator(__i0);
354 __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
Howard Hinnant17e485c2013-04-05 17:58:52 +0000355 if (i == nullptr && i0 != nullptr)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000356 i = __insert_iterator(__i);
357 __c_node* c = i != nullptr ? i->__c_ : nullptr;
358 if (c != c0)
359 {
360 if (c != nullptr)
361 c->__remove(i);
362 if (i != nullptr)
363 {
364 i->__c_ = nullptr;
365 if (c0 != nullptr)
366 {
367 i->__c_ = c0;
368 i->__c_->__add(i);
369 }
370 }
371 }
372}
373
374bool
375__libcpp_db::__dereferenceable(const void* __i) const
376{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000377#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000378 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000379#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000380 __i_node* i = __find_iterator(__i);
381 return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
382}
383
384bool
385__libcpp_db::__decrementable(const void* __i) const
386{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000387#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000388 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000389#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000390 __i_node* i = __find_iterator(__i);
391 return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
392}
393
394bool
395__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
396{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000397#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000398 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000399#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000400 __i_node* i = __find_iterator(__i);
401 return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
402}
403
404bool
405__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
406{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000407#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000408 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000409#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000410 __i_node* i = __find_iterator(__i);
411 return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
412}
413
414bool
Howard Hinnante6ff0b62013-08-02 00:26:35 +0000415__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
Howard Hinnant27e0e772011-09-14 18:33:51 +0000416{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000417#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000418 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000419#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000420 __i_node* i = __find_iterator(__i);
421 __i_node* j = __find_iterator(__j);
422 __c_node* ci = i != nullptr ? i->__c_ : nullptr;
423 __c_node* cj = j != nullptr ? j->__c_ : nullptr;
424 return ci != nullptr && ci == cj;
425}
426
427void
428__libcpp_db::swap(void* c1, void* c2)
429{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000430#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000431 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000432#endif
Howard Hinnant28b24882011-12-01 20:21:04 +0000433 size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000434 __c_node* p1 = __cbeg_[hc];
435 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
436 while (p1->__c_ != c1)
437 {
438 p1 = p1->__next_;
439 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
440 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000441 hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000442 __c_node* p2 = __cbeg_[hc];
443 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
444 while (p2->__c_ != c2)
445 {
446 p2 = p2->__next_;
447 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
448 }
449 std::swap(p1->beg_, p2->beg_);
450 std::swap(p1->end_, p2->end_);
451 std::swap(p1->cap_, p2->cap_);
452 for (__i_node** p = p1->beg_; p != p1->end_; ++p)
453 (*p)->__c_ = p1;
454 for (__i_node** p = p2->beg_; p != p2->end_; ++p)
455 (*p)->__c_ = p2;
456}
457
Howard Hinnantc90aa632011-09-16 19:52:23 +0000458void
459__libcpp_db::__insert_i(void* __i)
460{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000461#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnantc90aa632011-09-16 19:52:23 +0000462 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000463#endif
Howard Hinnantc90aa632011-09-16 19:52:23 +0000464 __insert_iterator(__i);
465}
466
Howard Hinnantb399c602011-09-27 23:55:03 +0000467void
468__c_node::__add(__i_node* i)
469{
470 if (end_ == cap_)
471 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000472 size_t nc = 2*static_cast<size_t>(cap_ - beg_);
Howard Hinnantb399c602011-09-27 23:55:03 +0000473 if (nc == 0)
474 nc = 1;
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000475 __i_node** beg =
476 static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));
Howard Hinnantb399c602011-09-27 23:55:03 +0000477 if (beg == nullptr)
Howard Hinnantc2834e62012-08-24 22:15:12 +0000478#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnantb399c602011-09-27 23:55:03 +0000479 throw bad_alloc();
Howard Hinnantc2834e62012-08-24 22:15:12 +0000480#else
481 abort();
482#endif
Howard Hinnantb399c602011-09-27 23:55:03 +0000483 if (nc > 1)
484 memcpy(beg, beg_, nc/2*sizeof(__i_node*));
485 free(beg_);
486 beg_ = beg;
487 end_ = beg_ + nc/2;
488 cap_ = beg_ + nc;
489 }
490 *end_++ = i;
491}
492
Howard Hinnant27e0e772011-09-14 18:33:51 +0000493// private api
494
495_LIBCPP_HIDDEN
496__i_node*
497__libcpp_db::__insert_iterator(void* __i)
498{
Howard Hinnant28b24882011-12-01 20:21:04 +0000499 if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
Howard Hinnant27e0e772011-09-14 18:33:51 +0000500 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000501 size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000502 __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(void*)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000503 if (ibeg == nullptr)
Howard Hinnantc2834e62012-08-24 22:15:12 +0000504#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000505 throw bad_alloc();
Howard Hinnantc2834e62012-08-24 22:15:12 +0000506#else
507 abort();
508#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000509 for (__i_node** p = __ibeg_; p != __iend_; ++p)
510 {
511 __i_node* q = *p;
512 while (q != nullptr)
513 {
514 size_t h = hash<void*>()(q->__i_) % nc;
515 __i_node* r = q->__next_;
516 q->__next_ = ibeg[h];
517 ibeg[h] = q;
518 q = r;
519 }
520 }
521 free(__ibeg_);
522 __ibeg_ = ibeg;
523 __iend_ = __ibeg_ + nc;
524 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000525 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000526 __i_node* p = __ibeg_[hi];
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000527 __i_node* r = __ibeg_[hi] =
528 static_cast<__i_node*>(malloc(sizeof(__i_node)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000529 if (r == nullptr)
Howard Hinnantc2834e62012-08-24 22:15:12 +0000530#ifndef _LIBCPP_NO_EXCEPTIONS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000531 throw bad_alloc();
Howard Hinnantc2834e62012-08-24 22:15:12 +0000532#else
533 abort();
534#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000535 ::new(r) __i_node(__i, p, nullptr);
536 ++__isz_;
537 return r;
538}
539
540_LIBCPP_HIDDEN
541__i_node*
542__libcpp_db::__find_iterator(const void* __i) const
543{
544 __i_node* r = nullptr;
545 if (__ibeg_ != __iend_)
546 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000547 size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000548 for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
549 {
550 if (nd->__i_ == __i)
551 {
552 r = nd;
553 break;
554 }
555 }
556 }
557 return r;
558}
559
560_LIBCPP_HIDDEN
561void
Howard Hinnant27e0e772011-09-14 18:33:51 +0000562__c_node::__remove(__i_node* p)
563{
564 __i_node** r = find(beg_, end_, p);
565 _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
566 if (--end_ != r)
Howard Hinnant28b24882011-12-01 20:21:04 +0000567 memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000568}
569
570_LIBCPP_END_NAMESPACE_STD