The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / jsregexp-inl.h @ 40c0f755

History | View | Annotate | Download (7.4 KB)

1
// Copyright 2008 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_JSREGEXP_INL_H_
29
#define V8_JSREGEXP_INL_H_
30

    
31

    
32
#include "jsregexp.h"
33
#include "regexp-macro-assembler.h"
34

    
35

    
36
namespace v8 { namespace internal {
37

    
38

    
39
template <typename C>
40
bool ZoneSplayTree<C>::Insert(const Key& key, Locator* locator) {
41
  if (is_empty()) {
42
    // If the tree is empty, insert the new node.
43
    root_ = new Node(key, C::kNoValue);
44
  } else {
45
    // Splay on the key to move the last node on the search path
46
    // for the key to the root of the tree.
47
    Splay(key);
48
    // Ignore repeated insertions with the same key.
49
    int cmp = C::Compare(key, root_->key_);
50
    if (cmp == 0) {
51
      locator->bind(root_);
52
      return false;
53
    }
54
    // Insert the new node.
55
    Node* node = new Node(key, C::kNoValue);
56
    if (cmp > 0) {
57
      node->left_ = root_;
58
      node->right_ = root_->right_;
59
      root_->right_ = NULL;
60
    } else {
61
      node->right_ = root_;
62
      node->left_ = root_->left_;
63
      root_->left_ = NULL;
64
    }
65
    root_ = node;
66
  }
67
  locator->bind(root_);
68
  return true;
69
}
70

    
71

    
72
template <typename C>
73
bool ZoneSplayTree<C>::Find(const Key& key, Locator* locator) {
74
  if (is_empty())
75
    return false;
76
  Splay(key);
77
  if (C::Compare(key, root_->key_) == 0) {
78
    locator->bind(root_);
79
    return true;
80
  } else {
81
    return false;
82
  }
83
}
84

    
85

    
86
template <typename C>
87
bool ZoneSplayTree<C>::FindGreatestLessThan(const Key& key,
88
                                            Locator* locator) {
89
  if (is_empty())
90
    return false;
91
  // Splay on the key to move the node with the given key or the last
92
  // node on the search path to the top of the tree.
93
  Splay(key);
94
  // Now the result is either the root node or the greatest node in
95
  // the left subtree.
96
  int cmp = C::Compare(root_->key_, key);
97
  if (cmp <= 0) {
98
    locator->bind(root_);
99
    return true;
100
  } else {
101
    Node* temp = root_;
102
    root_ = root_->left_;
103
    bool result = FindGreatest(locator);
104
    root_ = temp;
105
    return result;
106
  }
107
}
108

    
109

    
110
template <typename C>
111
bool ZoneSplayTree<C>::FindLeastGreaterThan(const Key& key,
112
                                            Locator* locator) {
113
  if (is_empty())
114
    return false;
115
  // Splay on the key to move the node with the given key or the last
116
  // node on the search path to the top of the tree.
117
  Splay(key);
118
  // Now the result is either the root node or the least node in
119
  // the right subtree.
120
  int cmp = C::Compare(root_->key_, key);
121
  if (cmp >= 0) {
122
    locator->bind(root_);
123
    return true;
124
  } else {
125
    Node* temp = root_;
126
    root_ = root_->right_;
127
    bool result = FindLeast(locator);
128
    root_ = temp;
129
    return result;
130
  }
131
}
132

    
133

    
134
template <typename C>
135
bool ZoneSplayTree<C>::FindGreatest(Locator* locator) {
136
  if (is_empty())
137
    return false;
138
  Node* current = root_;
139
  while (current->right_ != NULL)
140
    current = current->right_;
141
  locator->bind(current);
142
  return true;
143
}
144

    
145

    
146
template <typename C>
147
bool ZoneSplayTree<C>::FindLeast(Locator* locator) {
148
  if (is_empty())
149
    return false;
150
  Node* current = root_;
151
  while (current->left_ != NULL)
152
    current = current->left_;
153
  locator->bind(current);
154
  return true;
155
}
156

    
157

    
158
template <typename C>
159
bool ZoneSplayTree<C>::Remove(const Key& key) {
160
  // Bail if the tree is empty
161
  if (is_empty())
162
    return false;
163
  // Splay on the key to move the node with the given key to the top.
164
  Splay(key);
165
  // Bail if the key is not in the tree
166
  if (C::Compare(key, root_->key_) != 0)
167
    return false;
168
  if (root_->left_ == NULL) {
169
    // No left child, so the new tree is just the right child.
170
    root_ = root_->right_;
171
  } else {
172
    // Left child exists.
173
    Node* right = root_->right_;
174
    // Make the original left child the new root.
175
    root_ = root_->left_;
176
    // Splay to make sure that the new root has an empty right child.
177
    Splay(key);
178
    // Insert the original right child as the right child of the new
179
    // root.
180
    root_->right_ = right;
181
  }
182
  return true;
183
}
184

    
185

    
186
template <typename C>
187
void ZoneSplayTree<C>::Splay(const Key& key) {
188
  if (is_empty())
189
    return;
190
  Node dummy_node(C::kNoKey, C::kNoValue);
191
  // Create a dummy node.  The use of the dummy node is a bit
192
  // counter-intuitive: The right child of the dummy node will hold
193
  // the L tree of the algorithm.  The left child of the dummy node
194
  // will hold the R tree of the algorithm.  Using a dummy node, left
195
  // and right will always be nodes and we avoid special cases.
196
  Node* dummy = &dummy_node;
197
  Node* left = dummy;
198
  Node* right = dummy;
199
  Node* current = root_;
200
  while (true) {
201
    int cmp = C::Compare(key, current->key_);
202
    if (cmp < 0) {
203
      if (current->left_ == NULL)
204
        break;
205
      if (C::Compare(key, current->left_->key_) < 0) {
206
        // Rotate right.
207
        Node* temp = current->left_;
208
        current->left_ = temp->right_;
209
        temp->right_ = current;
210
        current = temp;
211
        if (current->left_ == NULL)
212
          break;
213
      }
214
      // Link right.
215
      right->left_ = current;
216
      right = current;
217
      current = current->left_;
218
    } else if (cmp > 0) {
219
      if (current->right_ == NULL)
220
        break;
221
      if (C::Compare(key, current->right_->key_) > 0) {
222
        // Rotate left.
223
        Node* temp = current->right_;
224
        current->right_ = temp->left_;
225
        temp->left_ = current;
226
        current = temp;
227
        if (current->right_ == NULL)
228
          break;
229
      }
230
      // Link left.
231
      left->right_ = current;
232
      left = current;
233
      current = current->right_;
234
    } else {
235
      break;
236
    }
237
  }
238
  // Assemble.
239
  left->right_ = current->left_;
240
  right->left_ = current->right_;
241
  current->left_ = dummy->right_;
242
  current->right_ = dummy->left_;
243
  root_ = current;
244
}
245

    
246

    
247
template <typename Node, class Callback>
248
static void DoForEach(Node* node, Callback* callback) {
249
  if (node == NULL) return;
250
  DoForEach<Node, Callback>(node->left(), callback);
251
  callback->Call(node->key(), node->value());
252
  DoForEach<Node, Callback>(node->right(), callback);
253
}
254

    
255

    
256
}}  // namespace v8::internal
257

    
258

    
259
#endif  // V8_JSREGEXP_INL_H_