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_/] [split_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_/split_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
split(key_const_reference r_key, PB_DS_CLASS_C_DEC& other)
45
{
46
  PB_DS_ASSERT_VALID((*this))
47
  PB_DS_ASSERT_VALID(other)
48
  branch_bag bag;
49
  leaf_pointer p_split_lf = split_prep(r_key, other, bag);
50
  if (p_split_lf == 0)
51
    {
52
      _GLIBCXX_DEBUG_ASSERT(bag.empty());
53
      PB_DS_ASSERT_VALID((*this))
54
      PB_DS_ASSERT_VALID(other)
55
      return;
56
    }
57
 
58
  _GLIBCXX_DEBUG_ASSERT(!bag.empty());
59
  other.clear();
60
 
61
  m_p_head->m_p_parent = rec_split(m_p_head->m_p_parent, pref_begin(p_split_lf),
62
                                   pref_end(p_split_lf), other, bag);
63
 
64
  m_p_head->m_p_parent->m_p_parent = m_p_head;
65
 
66
  head_pointer __ohead = other.m_p_head;
67
  __ohead->m_p_max = m_p_head->m_p_max;
68
  m_p_head->m_p_max = rightmost_descendant(m_p_head->m_p_parent);
69
  __ohead->m_p_min = other.leftmost_descendant(__ohead->m_p_parent);
70
 
71
  other.m_size = std::distance(other.PB_DS_CLASS_C_DEC::begin(),
72
                               other.PB_DS_CLASS_C_DEC::end());
73
  m_size -= other.m_size;
74
  PB_DS_ASSERT_VALID((*this))
75
  PB_DS_ASSERT_VALID(other)
76
}
77
 
78
PB_DS_CLASS_T_DEC
79
typename PB_DS_CLASS_C_DEC::leaf_pointer
80
PB_DS_CLASS_C_DEC::
81
split_prep(key_const_reference r_key, PB_DS_CLASS_C_DEC& other,
82
           branch_bag& r_bag)
83
{
84
  _GLIBCXX_DEBUG_ASSERT(r_bag.empty());
85
  if (m_size == 0)
86
    {
87
      other.clear();
88
      PB_DS_ASSERT_VALID((*this))
89
      PB_DS_ASSERT_VALID(other)
90
      return 0;
91
    }
92
 
93
  if (synth_access_traits::cmp_keys(r_key,
94
                                    PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_min)->value())))
95
    {
96
      other.clear();
97
      value_swap(other);
98
      PB_DS_ASSERT_VALID((*this))
99
      PB_DS_ASSERT_VALID(other)
100
      return 0;
101
    }
102
 
103
  if (!synth_access_traits::cmp_keys(r_key,
104
                                       PB_DS_V2F(static_cast<leaf_const_pointer>(m_p_head->m_p_max)->value())))
105
    {
106
      PB_DS_ASSERT_VALID((*this))
107
      PB_DS_ASSERT_VALID(other)
108
      return 0;
109
    }
110
 
111
  iterator it = lower_bound(r_key);
112
 
113
  if (!synth_access_traits::equal_keys(PB_DS_V2F(*it), r_key))
114
    --it;
115
 
116
  node_pointer p_nd = it.m_p_nd;
117
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == leaf_node);
118
  leaf_pointer p_ret_l = static_cast<leaf_pointer>(p_nd);
119
  while (p_nd->m_type != head_node)
120
    {
121
      r_bag.add_branch();
122
      p_nd = p_nd->m_p_parent;
123
    }
124
  _GLIBCXX_DEBUG_ONLY(debug_base::split(r_key,(synth_access_traits&)(*this), other);)
125
 
126
  return p_ret_l;
127
}
128
 
129
PB_DS_CLASS_T_DEC
130
typename PB_DS_CLASS_C_DEC::node_pointer
131
PB_DS_CLASS_C_DEC::
132
rec_split(node_pointer p_nd, a_const_iterator b_it, a_const_iterator e_it,
133
          PB_DS_CLASS_C_DEC& other, branch_bag& r_bag)
134
{
135
  if (p_nd->m_type == leaf_node)
136
    {
137
      _GLIBCXX_DEBUG_ASSERT(other.m_p_head->m_p_parent == 0);
138
      return p_nd;
139
    }
140
 
141
  _GLIBCXX_DEBUG_ASSERT(p_nd->m_type == i_node);
142
  inode_pointer p_ind = static_cast<inode_pointer>(p_nd);
143
 
144
  node_pointer pfirst = p_ind->get_child_node(b_it, e_it, this);
145
  node_pointer p_child_ret = rec_split(pfirst, b_it, e_it, other, r_bag);
146
  PB_DS_ASSERT_NODE_VALID(p_child_ret)
147
  p_ind->replace_child(p_child_ret, b_it, e_it, this);
148
  apply_update(p_ind, (node_update*)this);
149
 
150
  inode_iterator child_it = p_ind->get_child_it(b_it, e_it, this);
151
  const size_type lhs_dist = std::distance(p_ind->begin(), child_it);
152
  const size_type lhs_num_children = lhs_dist + 1;
153
  _GLIBCXX_DEBUG_ASSERT(lhs_num_children > 0);
154
 
155
  const size_type rhs_dist =  std::distance(p_ind->begin(), p_ind->end());
156
  size_type rhs_num_children = rhs_dist - lhs_num_children;
157
  if (rhs_num_children == 0)
158
    {
159
      apply_update(p_ind, (node_update*)this);
160
      return p_ind;
161
    }
162
 
163
  other.split_insert_branch(p_ind->get_e_ind(), b_it, child_it,
164
                            rhs_num_children, r_bag);
165
 
166
  child_it = p_ind->get_child_it(b_it, e_it, this);
167
  while (rhs_num_children != 0)
168
    {
169
      ++child_it;
170
      p_ind->remove_child(child_it);
171
      --rhs_num_children;
172
    }
173
  apply_update(p_ind, (node_update*)this);
174
 
175
  const size_type int_dist = std::distance(p_ind->begin(), p_ind->end());
176
  _GLIBCXX_DEBUG_ASSERT(int_dist >= 1);
177
  if (int_dist > 1)
178
    {
179
      p_ind->update_prefixes(this);
180
      PB_DS_ASSERT_NODE_VALID(p_ind)
181
      apply_update(p_ind, (node_update*)this);
182
      return p_ind;
183
    }
184
 
185
  node_pointer p_ret = *p_ind->begin();
186
  p_ind->~inode();
187
  s_inode_allocator.deallocate(p_ind, 1);
188
  apply_update(p_ret, (node_update*)this);
189
  return p_ret;
190
}
191
 
192
PB_DS_CLASS_T_DEC
193
void
194
PB_DS_CLASS_C_DEC::
195
split_insert_branch(size_type e_ind, a_const_iterator b_it,
196
                    inode_iterator child_b_it,
197
                    size_type num_children, branch_bag& r_bag)
198
{
199
#ifdef _GLIBCXX_DEBUG
200
  if (m_p_head->m_p_parent != 0)
201
    PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent)
202
#endif
203
 
204
  const size_type start = m_p_head->m_p_parent == 0 ? 0 : 1;
205
  const size_type total_num_children = start + num_children;
206
  if (total_num_children == 0)
207
    {
208
      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0);
209
      return;
210
    }
211
 
212
  if (total_num_children == 1)
213
    {
214
      if (m_p_head->m_p_parent != 0)
215
        {
216
          PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent)
217
          return;
218
        }
219
 
220
      _GLIBCXX_DEBUG_ASSERT(m_p_head->m_p_parent == 0);
221
      ++child_b_it;
222
      m_p_head->m_p_parent = *child_b_it;
223
      m_p_head->m_p_parent->m_p_parent = m_p_head;
224
      apply_update(m_p_head->m_p_parent, (node_update*)this);
225
      PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent)
226
      return;
227
    }
228
 
229
  _GLIBCXX_DEBUG_ASSERT(total_num_children > 1);
230
  inode_pointer p_new_root = r_bag.get_branch();
231
  new (p_new_root) inode(e_ind, b_it);
232
  size_type num_inserted = 0;
233
  while (num_inserted++ < num_children)
234
    {
235
      ++child_b_it;
236
      PB_DS_ASSERT_NODE_VALID((*child_b_it))
237
      p_new_root->add_child(*child_b_it, pref_begin(*child_b_it),
238
                            pref_end(*child_b_it), this);
239
    }
240
 
241
  if (m_p_head->m_p_parent != 0)
242
    p_new_root->add_child(m_p_head->m_p_parent,
243
                          pref_begin(m_p_head->m_p_parent),
244
                          pref_end(m_p_head->m_p_parent), this);
245
 
246
  m_p_head->m_p_parent = p_new_root;
247
  p_new_root->m_p_parent = m_p_head;
248
  apply_update(m_p_head->m_p_parent, (node_update*)this);
249
  PB_DS_ASSERT_NODE_VALID(m_p_head->m_p_parent)
250
}

powered by: WebSVN 2.1.0

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