OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [ext/] [pb_ds/] [detail/] [pat_trie_/] [insert_join_fn_imps.hpp] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
// -*- C++ -*-
2
 
3
// Copyright (C) 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the terms
7
// of the GNU General Public License as published by the Free Software
8
// Foundation; either version 3, or (at your option) any later
9
// version.
10
 
11
// This library is distributed in the hope that it will be useful, but
12
// WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
// General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// <http://www.gnu.org/licenses/>.
24
 
25
// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
26
 
27
// Permission to use, copy, modify, sell, and distribute this software
28
// is hereby granted without fee, provided that the above copyright
29
// notice appears in all copies, and that both that copyright notice
30
// and this permission notice appear in supporting documentation. None
31
// of the above authors, nor IBM Haifa Research Laboratories, make any
32
// representation about the suitability of this software for any
33
// purpose. It is provided "as is" without express or implied
34
// warranty.
35
 
36
/**
37
 * @file pat_trie_/insert_join_fn_imps.hpp
38
 * Contains an implementation class for pat_trie.
39
 */
40
 
41
PB_DS_CLASS_T_DEC
42
void
43
PB_DS_CLASS_C_DEC::
44
join(PB_DS_CLASS_C_DEC& other)
45
{
46
  PB_DS_ASSERT_VALID((*this))
47
  PB_DS_ASSERT_VALID(other)
48
  branch_bag bag;
49
  if (!join_prep(other, bag))
50
    {
51
      PB_DS_ASSERT_VALID((*this))
52
      PB_DS_ASSERT_VALID(other)
53
      return;
54
    }
55
 
56
  m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent,
57
                                  other.m_p_head->m_p_parent, 0, bag);
58
 
59
  m_p_head->m_p_parent->m_p_parent = m_p_head;
60
  m_size += other.m_size;
61
  other.initialize();
62
  PB_DS_ASSERT_VALID(other)
63
  m_p_head->m_p_min = leftmost_descendant(m_p_head->m_p_parent);
64
  m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent);
65
  PB_DS_ASSERT_VALID((*this))
66
}
67
 
68
PB_DS_CLASS_T_DEC
69
bool
70
PB_DS_CLASS_C_DEC::
71
join_prep(PB_DS_CLASS_C_DEC& other, branch_bag& r_bag)
72
{
73
  PB_DS_ASSERT_VALID((*this))
74
  PB_DS_ASSERT_VALID(other)
75
  if (other.m_size == 0)
76
    return false;
77
 
78
  if (m_size == 0)
79
    {
80
      value_swap(other);
81
      return false;
82
    }
83
 
84
  const bool greater =
85
    synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_max)->value()),
86
                                    PB_DS_V2F(static_cast<leaf_const_pointer>(other.m_p_head->m_p_min)->value()));
87
 
88
  const bool lesser =
89
    synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(other.m_p_head->m_p_max)->value()),
90
                                    PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_min)->value()));
91
 
92
  if (!greater && !lesser)
93
    __throw_join_error();
94
 
95
  rec_join_prep(m_p_head->m_p_parent, other.m_p_head->m_p_parent, r_bag);
96
  _GLIBCXX_DEBUG_ONLY(debug_base::join(other, false);)
97
  return true;
98
}
99
 
100
PB_DS_CLASS_T_DEC
101
void
102
PB_DS_CLASS_C_DEC::
103
rec_join_prep(node_const_pointer p_l, node_const_pointer p_r,
104
              branch_bag& r_bag)
105
{
106
  if (p_l->m_type == leaf_node)
107
    {
108
      if (p_r->m_type == leaf_node)
109
        {
110
          rec_join_prep(static_cast<leaf_const_pointer>(p_l),
111
                        static_cast<leaf_const_pointer>(p_r), r_bag);
112
          return;
113
        }
114
 
115
      _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node);
116
      rec_join_prep(static_cast<leaf_const_pointer>(p_l),
117
                    static_cast<inode_const_pointer>(p_r), r_bag);
118
      return;
119
    }
120
 
121
  _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node);
122
  if (p_r->m_type == leaf_node)
123
    {
124
      rec_join_prep(static_cast<inode_const_pointer>(p_l),
125
                    static_cast<leaf_const_pointer>(p_r), r_bag);
126
      return;
127
    }
128
 
129
  _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node);
130
 
131
  rec_join_prep(static_cast<inode_const_pointer>(p_l),
132
                static_cast<inode_const_pointer>(p_r), r_bag);
133
}
134
 
135
PB_DS_CLASS_T_DEC
136
void
137
PB_DS_CLASS_C_DEC::
138
rec_join_prep(leaf_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/,
139
              branch_bag& r_bag)
140
{ r_bag.add_branch(); }
141
 
142
PB_DS_CLASS_T_DEC
143
void
144
PB_DS_CLASS_C_DEC::
145
rec_join_prep(leaf_const_pointer /*p_l*/, inode_const_pointer /*p_r*/,
146
              branch_bag& r_bag)
147
{ r_bag.add_branch(); }
148
 
149
PB_DS_CLASS_T_DEC
150
void
151
PB_DS_CLASS_C_DEC::
152
rec_join_prep(inode_const_pointer /*p_l*/, leaf_const_pointer /*p_r*/,
153
              branch_bag& r_bag)
154
{ r_bag.add_branch(); }
155
 
156
PB_DS_CLASS_T_DEC
157
void
158
PB_DS_CLASS_C_DEC::
159
rec_join_prep(inode_const_pointer p_l, inode_const_pointer p_r,
160
              branch_bag& r_bag)
161
{
162
  if (p_l->get_e_ind() == p_r->get_e_ind() &&
163
      synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(),
164
                                            p_r->pref_b_it(), p_r->pref_e_it()))
165
    {
166
      for (typename inode::const_iterator it = p_r->begin();
167
           it != p_r->end(); ++ it)
168
        {
169
          node_const_pointer p_l_join_child = p_l->get_join_child(*it, this);
170
          if (p_l_join_child != 0)
171
            rec_join_prep(p_l_join_child, * it, r_bag);
172
        }
173
      return;
174
    }
175
 
176
  if (p_r->get_e_ind() < p_l->get_e_ind() &&
177
      p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this))
178
    {
179
      node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this);
180
      if (p_r_join_child != 0)
181
        rec_join_prep(p_r_join_child, p_l, r_bag);
182
      return;
183
    }
184
 
185
  if (p_r->get_e_ind() < p_l->get_e_ind() &&
186
      p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this))
187
    {
188
      node_const_pointer p_r_join_child = p_r->get_join_child(p_l, this);
189
      if (p_r_join_child != 0)
190
        rec_join_prep(p_r_join_child, p_l, r_bag);
191
      return;
192
    }
193
  r_bag.add_branch();
194
}
195
 
196
PB_DS_CLASS_T_DEC
197
typename PB_DS_CLASS_C_DEC::node_pointer
198
PB_DS_CLASS_C_DEC::
199
rec_join(node_pointer p_l, node_pointer p_r, size_type checked_ind,
200
         branch_bag& r_bag)
201
{
202
  _GLIBCXX_DEBUG_ASSERT(p_r != 0);
203
  if (p_l == 0)
204
    {
205
      apply_update(p_r, (node_update*)this);
206
      return (p_r);
207
    }
208
 
209
  if (p_l->m_type == leaf_node)
210
    {
211
      if (p_r->m_type == leaf_node)
212
        {
213
          node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l),
214
                                        static_cast<leaf_pointer>(p_r), r_bag);
215
          apply_update(p_ret, (node_update*)this);
216
          return p_ret;
217
        }
218
 
219
      _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node);
220
      node_pointer p_ret = rec_join(static_cast<leaf_pointer>(p_l),
221
                                    static_cast<inode_pointer>(p_r),
222
                                    checked_ind, r_bag);
223
      apply_update(p_ret, (node_update*)this);
224
      return p_ret;
225
    }
226
 
227
  _GLIBCXX_DEBUG_ASSERT(p_l->m_type == i_node);
228
  if (p_r->m_type == leaf_node)
229
    {
230
      node_pointer p_ret = rec_join(static_cast<inode_pointer>(p_l),
231
                                    static_cast<leaf_pointer>(p_r),
232
                                    checked_ind, r_bag);
233
      apply_update(p_ret, (node_update*)this);
234
      return p_ret;
235
    }
236
 
237
  _GLIBCXX_DEBUG_ASSERT(p_r->m_type == i_node);
238
  node_pointer p_ret = rec_join(static_cast<inode_pointer>(p_l),
239
                                static_cast<inode_pointer>(p_r),
240
                                r_bag);
241
 
242
  apply_update(p_ret, (node_update*)this);
243
  return p_ret;
244
}
245
 
246
PB_DS_CLASS_T_DEC
247
typename PB_DS_CLASS_C_DEC::node_pointer
248
PB_DS_CLASS_C_DEC::
249
rec_join(leaf_pointer p_l, leaf_pointer p_r, branch_bag& r_bag)
250
{
251
  _GLIBCXX_DEBUG_ASSERT(p_r != 0);
252
  if (p_l == 0)
253
    return (p_r);
254
  node_pointer p_ret = insert_branch(p_l, p_r, r_bag);
255
  _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == 2);
256
  return p_ret;
257
}
258
 
259
PB_DS_CLASS_T_DEC
260
typename PB_DS_CLASS_C_DEC::node_pointer
261
PB_DS_CLASS_C_DEC::
262
rec_join(leaf_pointer p_l, inode_pointer p_r, size_type checked_ind,
263
         branch_bag& r_bag)
264
{
265
#ifdef _GLIBCXX_DEBUG
266
  const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l);
267
  const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r);
268
#endif
269
 
270
  _GLIBCXX_DEBUG_ASSERT(p_r != 0);
271
  node_pointer p_ret = rec_join(p_r, p_l, checked_ind, r_bag);
272
  _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs);
273
  return p_ret;
274
}
275
 
276
PB_DS_CLASS_T_DEC
277
typename PB_DS_CLASS_C_DEC::node_pointer
278
PB_DS_CLASS_C_DEC::
279
rec_join(inode_pointer p_l, leaf_pointer p_r, size_type checked_ind, branch_bag& r_bag)
280
{
281
  _GLIBCXX_DEBUG_ASSERT(p_l != 0);
282
  _GLIBCXX_DEBUG_ASSERT(p_r != 0);
283
 
284
#ifdef _GLIBCXX_DEBUG
285
  const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l);
286
  const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r);
287
#endif
288
 
289
  if (!p_l->should_be_mine(pref_begin(p_r), pref_end(p_r), checked_ind, this))
290
    {
291
      node_pointer p_ret = insert_branch(p_l, p_r, r_bag);
292
      PB_DS_ASSERT_NODE_VALID(p_ret)
293
      _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) ==
294
                            lhs_leafs + rhs_leafs);
295
      return p_ret;
296
    }
297
 
298
  node_pointer p_pot_child = p_l->add_child(p_r, pref_begin(p_r),
299
                                            pref_end(p_r), this);
300
  if (p_pot_child != p_r)
301
    {
302
      node_pointer p_new_child = rec_join(p_pot_child, p_r, p_l->get_e_ind(),
303
                                          r_bag);
304
 
305
      p_l->replace_child(p_new_child, pref_begin(p_new_child),
306
                         pref_end(p_new_child), this);
307
    }
308
 
309
  PB_DS_ASSERT_NODE_VALID(p_l)
310
  _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs);
311
  return p_l;
312
}
313
 
314
PB_DS_CLASS_T_DEC
315
typename PB_DS_CLASS_C_DEC::node_pointer
316
PB_DS_CLASS_C_DEC::
317
rec_join(inode_pointer p_l, inode_pointer p_r,
318
         branch_bag& r_bag)
319
{
320
  _GLIBCXX_DEBUG_ASSERT(p_l != 0);
321
  _GLIBCXX_DEBUG_ASSERT(p_r != 0);
322
 
323
#ifdef _GLIBCXX_DEBUG
324
  const size_type lhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_l);
325
  const size_type rhs_leafs = PB_DS_RECURSIVE_COUNT_LEAFS(p_r);
326
#endif
327
 
328
  if (p_l->get_e_ind() == p_r->get_e_ind() &&
329
      synth_access_traits::equal_prefixes(p_l->pref_b_it(), p_l->pref_e_it(),
330
                                            p_r->pref_b_it(), p_r->pref_e_it()))
331
    {
332
      for (typename inode::iterator it = p_r->begin();
333
           it != p_r->end(); ++ it)
334
        {
335
          node_pointer p_new_child = rec_join(p_l->get_join_child(*it, this),
336
                                              * it, 0, r_bag);
337
          p_l->replace_child(p_new_child, pref_begin(p_new_child),
338
                             pref_end(p_new_child), this);
339
        }
340
 
341
      p_r->~inode();
342
      s_inode_allocator.deallocate(p_r, 1);
343
      PB_DS_ASSERT_NODE_VALID(p_l)
344
      _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_l) == lhs_leafs + rhs_leafs);
345
      return p_l;
346
    }
347
 
348
  if (p_l->get_e_ind() < p_r->get_e_ind() &&
349
      p_l->should_be_mine(p_r->pref_b_it(), p_r->pref_e_it(), 0, this))
350
    {
351
      node_pointer p_new_child = rec_join(p_l->get_join_child(p_r, this),
352
                                          p_r, 0, r_bag);
353
      p_l->replace_child(p_new_child, pref_begin(p_new_child),
354
                         pref_end(p_new_child), this);
355
      PB_DS_ASSERT_NODE_VALID(p_l)
356
      return p_l;
357
    }
358
 
359
  if (p_r->get_e_ind() < p_l->get_e_ind() &&
360
      p_r->should_be_mine(p_l->pref_b_it(), p_l->pref_e_it(), 0, this))
361
    {
362
      node_pointer p_new_child = rec_join(p_r->get_join_child(p_l, this), p_l,
363
                                          0, r_bag);
364
 
365
      p_r->replace_child(p_new_child, pref_begin(p_new_child),
366
                         pref_end(p_new_child), this);
367
 
368
      PB_DS_ASSERT_NODE_VALID(p_r)
369
      _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_r) == lhs_leafs + rhs_leafs);
370
      return p_r;
371
    }
372
 
373
  node_pointer p_ret = insert_branch(p_l, p_r, r_bag);
374
  PB_DS_ASSERT_NODE_VALID(p_ret)
375
  _GLIBCXX_DEBUG_ASSERT(PB_DS_RECURSIVE_COUNT_LEAFS(p_ret) == lhs_leafs + rhs_leafs);
376
  return p_ret;
377
}
378
 
379
PB_DS_CLASS_T_DEC
380
inline std::pair<typename PB_DS_CLASS_C_DEC::iterator, bool>
381
PB_DS_CLASS_C_DEC::
382
insert(const_reference r_val)
383
{
384
  node_pointer p_lf = find_imp(PB_DS_V2F(r_val));
385
  if (p_lf != 0 && p_lf->m_type == leaf_node &&
386
      synth_access_traits::equal_keys(PB_DS_V2F(static_cast<leaf_pointer>(p_lf)->value()), PB_DS_V2F(r_val)))
387
    {
388
      PB_DS_CHECK_KEY_EXISTS(PB_DS_V2F(r_val))
389
      PB_DS_ASSERT_VALID((*this))
390
      return std::make_pair(iterator(p_lf), false);
391
    }
392
 
393
  PB_DS_CHECK_KEY_DOES_NOT_EXIST(PB_DS_V2F(r_val))
394
 
395
  leaf_pointer p_new_lf = s_leaf_allocator.allocate(1);
396
  cond_dealtor cond(p_new_lf);
397
 
398
  new (p_new_lf) leaf(r_val);
399
  apply_update(p_new_lf, (node_update*)this);
400
  cond.set_call_destructor();
401
  branch_bag bag;
402
  bag.add_branch();
403
  m_p_head->m_p_parent = rec_join(m_p_head->m_p_parent, p_new_lf, 0, bag);
404
  m_p_head->m_p_parent->m_p_parent = m_p_head;
405
  cond.set_no_action_dtor();
406
  ++m_size;
407
  update_min_max_for_inserted_leaf(p_new_lf);
408
  _GLIBCXX_DEBUG_ONLY(debug_base::insert_new(PB_DS_V2F(r_val));)
409
  PB_DS_ASSERT_VALID((*this))
410
  return std::make_pair(point_iterator(p_new_lf), true);
411
}
412
 
413
PB_DS_CLASS_T_DEC
414
typename PB_DS_CLASS_C_DEC::size_type
415
PB_DS_CLASS_C_DEC::
416
keys_diff_ind(typename access_traits::const_iterator b_l,
417
              typename access_traits::const_iterator e_l,
418
              typename access_traits::const_iterator b_r,
419
              typename access_traits::const_iterator e_r)
420
{
421
  size_type diff_pos = 0;
422
  while (b_l != e_l)
423
    {
424
      if (b_r == e_r)
425
        return (diff_pos);
426
      if (access_traits::e_pos(*b_l) != access_traits::e_pos(*b_r))
427
        return (diff_pos);
428
      ++b_l;
429
      ++b_r;
430
      ++diff_pos;
431
    }
432
  _GLIBCXX_DEBUG_ASSERT(b_r != e_r);
433
  return diff_pos;
434
}
435
 
436
PB_DS_CLASS_T_DEC
437
typename PB_DS_CLASS_C_DEC::inode_pointer
438
PB_DS_CLASS_C_DEC::
439
insert_branch(node_pointer p_l, node_pointer p_r, branch_bag& r_bag)
440
{
441
  typename synth_access_traits::const_iterator left_b_it = pref_begin(p_l);
442
  typename synth_access_traits::const_iterator left_e_it = pref_end(p_l);
443
  typename synth_access_traits::const_iterator right_b_it = pref_begin(p_r);
444
  typename synth_access_traits::const_iterator right_e_it = pref_end(p_r);
445
 
446
  const size_type diff_ind = keys_diff_ind(left_b_it, left_e_it,
447
                                           right_b_it, right_e_it);
448
 
449
  inode_pointer p_new_nd = r_bag.get_branch();
450
  new (p_new_nd) inode(diff_ind, left_b_it);
451
  p_new_nd->add_child(p_l, left_b_it, left_e_it, this);
452
  p_new_nd->add_child(p_r, right_b_it, right_e_it, this);
453
  p_l->m_p_parent = p_new_nd;
454
  p_r->m_p_parent = p_new_nd;
455
  PB_DS_ASSERT_NODE_VALID(p_new_nd)
456
  return (p_new_nd);
457
}
458
 
459
PB_DS_CLASS_T_DEC
460
void
461
PB_DS_CLASS_C_DEC::
462
update_min_max_for_inserted_leaf(leaf_pointer p_new_lf)
463
{
464
  if (m_p_head->m_p_min == m_p_head ||
465
      synth_access_traits::cmp_keys(PB_DS_V2F(p_new_lf->value()),
466
                                      PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_min)->value())))
467
    m_p_head->m_p_min = p_new_lf;
468
 
469
  if (m_p_head->m_p_max == m_p_head ||
470
      synth_access_traits::cmp_keys(PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_max)->value()), PB_DS_V2F(p_new_lf->value())))
471
    m_p_head->m_p_max = p_new_lf;
472
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.