blob: d46935cc9ed603a19499496dbf671ac71d59908a [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)
Marshall Clow8fea1612016-08-25 15:09:01 +0000155 __throw_bad_alloc();
156
Howard Hinnant27e0e772011-09-14 18:33:51 +0000157 for (__c_node** p = __cbeg_; p != __cend_; ++p)
158 {
159 __c_node* q = *p;
160 while (q != nullptr)
161 {
162 size_t h = hash<void*>()(q->__c_) % nc;
163 __c_node* r = q->__next_;
164 q->__next_ = cbeg[h];
165 cbeg[h] = q;
166 q = r;
167 }
168 }
169 free(__cbeg_);
170 __cbeg_ = cbeg;
171 __cend_ = __cbeg_ + nc;
172 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000173 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000174 __c_node* p = __cbeg_[hc];
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000175 __c_node* r = __cbeg_[hc] =
176 static_cast<__c_node*>(malloc(sizeof(__c_node)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000177 if (__cbeg_[hc] == nullptr)
Marshall Clow8fea1612016-08-25 15:09:01 +0000178 __throw_bad_alloc();
179
Howard Hinnant27e0e772011-09-14 18:33:51 +0000180 r->__c_ = __c;
181 r->__next_ = p;
182 ++__csz_;
183 return r;
184}
185
186void
187__libcpp_db::__erase_i(void* __i)
188{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000189#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000190 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000191#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000192 if (__ibeg_ != __iend_)
193 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000194 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000195 __i_node* p = __ibeg_[hi];
196 if (p != nullptr)
197 {
198 __i_node* q = nullptr;
199 while (p->__i_ != __i)
200 {
201 q = p;
202 p = p->__next_;
203 if (p == nullptr)
204 return;
205 }
206 if (q == nullptr)
207 __ibeg_[hi] = p->__next_;
208 else
209 q->__next_ = p->__next_;
210 __c_node* c = p->__c_;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000211 --__isz_;
212 if (c != nullptr)
213 c->__remove(p);
Eric Fiselier799b25d2015-03-19 03:20:02 +0000214 free(p);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000215 }
216 }
217}
218
219void
220__libcpp_db::__invalidate_all(void* __c)
221{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000222#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000223 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000224#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000225 if (__cend_ != __cbeg_)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000226 {
Howard Hinnant8ea98242013-08-23 17:37:05 +0000227 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
228 __c_node* p = __cbeg_[hc];
229 if (p == nullptr)
230 return;
231 while (p->__c_ != __c)
232 {
233 p = p->__next_;
234 if (p == nullptr)
235 return;
236 }
237 while (p->end_ != p->beg_)
238 {
239 --p->end_;
240 (*p->end_)->__c_ = nullptr;
241 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000242 }
243}
244
245__c_node*
246__libcpp_db::__find_c_and_lock(void* __c) const
247{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000248#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000249 mut().lock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000250#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000251 if (__cend_ == __cbeg_)
252 {
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000253#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant8ea98242013-08-23 17:37:05 +0000254 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000255#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000256 return nullptr;
257 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000258 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000259 __c_node* p = __cbeg_[hc];
Howard Hinnant8ea98242013-08-23 17:37:05 +0000260 if (p == nullptr)
261 {
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000262#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant8ea98242013-08-23 17:37:05 +0000263 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000264#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000265 return nullptr;
266 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000267 while (p->__c_ != __c)
268 {
269 p = p->__next_;
Howard Hinnant8ea98242013-08-23 17:37:05 +0000270 if (p == nullptr)
271 {
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000272#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant8ea98242013-08-23 17:37:05 +0000273 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000274#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000275 return nullptr;
276 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000277 }
278 return p;
279}
280
Howard Hinnantb399c602011-09-27 23:55:03 +0000281__c_node*
282__libcpp_db::__find_c(void* __c) const
283{
Howard Hinnant28b24882011-12-01 20:21:04 +0000284 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnantb399c602011-09-27 23:55:03 +0000285 __c_node* p = __cbeg_[hc];
286 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
287 while (p->__c_ != __c)
288 {
289 p = p->__next_;
290 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
291 }
292 return p;
293}
294
Howard Hinnant27e0e772011-09-14 18:33:51 +0000295void
296__libcpp_db::unlock() const
297{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000298#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000299 mut().unlock();
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000300#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000301}
302
303void
304__libcpp_db::__erase_c(void* __c)
305{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000306#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000307 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000308#endif
Howard Hinnant8ea98242013-08-23 17:37:05 +0000309 if (__cend_ != __cbeg_)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000310 {
Howard Hinnant8ea98242013-08-23 17:37:05 +0000311 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
312 __c_node* p = __cbeg_[hc];
313 if (p == nullptr)
314 return;
315 __c_node* q = nullptr;
316 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
317 while (p->__c_ != __c)
318 {
319 q = p;
320 p = p->__next_;
321 if (p == nullptr)
322 return;
323 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
324 }
325 if (q == nullptr)
326 __cbeg_[hc] = p->__next_;
327 else
328 q->__next_ = p->__next_;
329 while (p->end_ != p->beg_)
330 {
331 --p->end_;
332 (*p->end_)->__c_ = nullptr;
333 }
334 free(p->beg_);
335 free(p);
336 --__csz_;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000337 }
Howard Hinnant27e0e772011-09-14 18:33:51 +0000338}
339
340void
341__libcpp_db::__iterator_copy(void* __i, const void* __i0)
342{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000343#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000344 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000345#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000346 __i_node* i = __find_iterator(__i);
347 __i_node* i0 = __find_iterator(__i0);
348 __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
Howard Hinnant17e485c2013-04-05 17:58:52 +0000349 if (i == nullptr && i0 != nullptr)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000350 i = __insert_iterator(__i);
351 __c_node* c = i != nullptr ? i->__c_ : nullptr;
352 if (c != c0)
353 {
354 if (c != nullptr)
355 c->__remove(i);
356 if (i != nullptr)
357 {
358 i->__c_ = nullptr;
359 if (c0 != nullptr)
360 {
361 i->__c_ = c0;
362 i->__c_->__add(i);
363 }
364 }
365 }
366}
367
368bool
369__libcpp_db::__dereferenceable(const void* __i) const
370{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000371#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000372 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000373#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000374 __i_node* i = __find_iterator(__i);
375 return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
376}
377
378bool
379__libcpp_db::__decrementable(const void* __i) const
380{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000381#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000382 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000383#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000384 __i_node* i = __find_iterator(__i);
385 return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
386}
387
388bool
389__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
390{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000391#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000392 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000393#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000394 __i_node* i = __find_iterator(__i);
395 return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
396}
397
398bool
399__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
400{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000401#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000402 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000403#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000404 __i_node* i = __find_iterator(__i);
405 return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
406}
407
408bool
Howard Hinnante6ff0b62013-08-02 00:26:35 +0000409__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
Howard Hinnant27e0e772011-09-14 18:33:51 +0000410{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000411#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000412 RLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000413#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000414 __i_node* i = __find_iterator(__i);
415 __i_node* j = __find_iterator(__j);
416 __c_node* ci = i != nullptr ? i->__c_ : nullptr;
417 __c_node* cj = j != nullptr ? j->__c_ : nullptr;
418 return ci != nullptr && ci == cj;
419}
420
421void
422__libcpp_db::swap(void* c1, void* c2)
423{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000424#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnant27e0e772011-09-14 18:33:51 +0000425 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000426#endif
Howard Hinnant28b24882011-12-01 20:21:04 +0000427 size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000428 __c_node* p1 = __cbeg_[hc];
429 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
430 while (p1->__c_ != c1)
431 {
432 p1 = p1->__next_;
433 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
434 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000435 hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000436 __c_node* p2 = __cbeg_[hc];
437 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
438 while (p2->__c_ != c2)
439 {
440 p2 = p2->__next_;
441 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
442 }
443 std::swap(p1->beg_, p2->beg_);
444 std::swap(p1->end_, p2->end_);
445 std::swap(p1->cap_, p2->cap_);
446 for (__i_node** p = p1->beg_; p != p1->end_; ++p)
447 (*p)->__c_ = p1;
448 for (__i_node** p = p2->beg_; p != p2->end_; ++p)
449 (*p)->__c_ = p2;
450}
451
Howard Hinnantc90aa632011-09-16 19:52:23 +0000452void
453__libcpp_db::__insert_i(void* __i)
454{
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000455#ifndef _LIBCPP_HAS_NO_THREADS
Howard Hinnantc90aa632011-09-16 19:52:23 +0000456 WLock _(mut());
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000457#endif
Howard Hinnantc90aa632011-09-16 19:52:23 +0000458 __insert_iterator(__i);
459}
460
Howard Hinnantb399c602011-09-27 23:55:03 +0000461void
462__c_node::__add(__i_node* i)
463{
464 if (end_ == cap_)
465 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000466 size_t nc = 2*static_cast<size_t>(cap_ - beg_);
Howard Hinnantb399c602011-09-27 23:55:03 +0000467 if (nc == 0)
468 nc = 1;
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000469 __i_node** beg =
470 static_cast<__i_node**>(malloc(nc * sizeof(__i_node*)));
Howard Hinnantb399c602011-09-27 23:55:03 +0000471 if (beg == nullptr)
Marshall Clow8fea1612016-08-25 15:09:01 +0000472 __throw_bad_alloc();
473
Howard Hinnantb399c602011-09-27 23:55:03 +0000474 if (nc > 1)
475 memcpy(beg, beg_, nc/2*sizeof(__i_node*));
476 free(beg_);
477 beg_ = beg;
478 end_ = beg_ + nc/2;
479 cap_ = beg_ + nc;
480 }
481 *end_++ = i;
482}
483
Howard Hinnant27e0e772011-09-14 18:33:51 +0000484// private api
485
486_LIBCPP_HIDDEN
487__i_node*
488__libcpp_db::__insert_iterator(void* __i)
489{
Howard Hinnant28b24882011-12-01 20:21:04 +0000490 if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
Howard Hinnant27e0e772011-09-14 18:33:51 +0000491 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000492 size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000493 __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(void*)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000494 if (ibeg == nullptr)
Marshall Clow8fea1612016-08-25 15:09:01 +0000495 __throw_bad_alloc();
496
Howard Hinnant27e0e772011-09-14 18:33:51 +0000497 for (__i_node** p = __ibeg_; p != __iend_; ++p)
498 {
499 __i_node* q = *p;
500 while (q != nullptr)
501 {
502 size_t h = hash<void*>()(q->__i_) % nc;
503 __i_node* r = q->__next_;
504 q->__next_ = ibeg[h];
505 ibeg[h] = q;
506 q = r;
507 }
508 }
509 free(__ibeg_);
510 __ibeg_ = ibeg;
511 __iend_ = __ibeg_ + nc;
512 }
Howard Hinnant28b24882011-12-01 20:21:04 +0000513 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000514 __i_node* p = __ibeg_[hi];
Joerg Sonnenberger0962ed52013-04-27 19:13:31 +0000515 __i_node* r = __ibeg_[hi] =
516 static_cast<__i_node*>(malloc(sizeof(__i_node)));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000517 if (r == nullptr)
Marshall Clow8fea1612016-08-25 15:09:01 +0000518 __throw_bad_alloc();
519
Howard Hinnant27e0e772011-09-14 18:33:51 +0000520 ::new(r) __i_node(__i, p, nullptr);
521 ++__isz_;
522 return r;
523}
524
525_LIBCPP_HIDDEN
526__i_node*
527__libcpp_db::__find_iterator(const void* __i) const
528{
529 __i_node* r = nullptr;
530 if (__ibeg_ != __iend_)
531 {
Howard Hinnant28b24882011-12-01 20:21:04 +0000532 size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000533 for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
534 {
535 if (nd->__i_ == __i)
536 {
537 r = nd;
538 break;
539 }
540 }
541 }
542 return r;
543}
544
545_LIBCPP_HIDDEN
546void
Howard Hinnant27e0e772011-09-14 18:33:51 +0000547__c_node::__remove(__i_node* p)
548{
549 __i_node** r = find(beg_, end_, p);
550 _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
551 if (--end_ != r)
Howard Hinnant28b24882011-12-01 20:21:04 +0000552 memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
Howard Hinnant27e0e772011-09-14 18:33:51 +0000553}
554
555_LIBCPP_END_NAMESPACE_STD