All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
ec31ee9)
Removes catastrophically quadratic behavior on nodes with very many siblings.
* fixed unnecessary slowdown when long list literals where found in a file
* fixed unnecessary slowdown when long list literals where found in a file
+* fixed unnecessary slowdown on AST nodes with very many siblings
+
else:
l_children.append(ch)
assert found, (self.children, self, new)
else:
l_children.append(ch)
assert found, (self.children, self, new)
self.parent.children = l_children
self.parent.children = l_children
+ self.parent.changed()
+ self.parent.invalidate_sibling_maps()
for x in new:
x.parent = self.parent
self.parent = None
for x in new:
x.parent = self.parent
self.parent = None
if self.parent:
for i, node in enumerate(self.parent.children):
if node is self:
if self.parent:
for i, node in enumerate(self.parent.children):
if node is self:
del self.parent.children[i]
del self.parent.children[i]
+ self.parent.changed()
+ self.parent.invalidate_sibling_maps()
self.parent = None
return i
self.parent = None
return i
if self.parent is None:
return None
if self.parent is None:
return None
- # Can't use index(); we need to test by identity
- for i, child in enumerate(self.parent.children):
- if child is self:
- try:
- return self.parent.children[i+1]
- except IndexError:
- return None
+ if self.parent.next_sibling_map is None:
+ self.parent.update_sibling_maps()
+ return self.parent.next_sibling_map[id(self)]
@property
def prev_sibling(self):
@property
def prev_sibling(self):
if self.parent is None:
return None
if self.parent is None:
return None
- # Can't use index(); we need to test by identity
- for i, child in enumerate(self.parent.children):
- if child is self:
- if i == 0:
- return None
- return self.parent.children[i-1]
+ if self.parent.prev_sibling_map is None:
+ self.parent.update_sibling_maps()
+ return self.parent.prev_sibling_map[id(self)]
def leaves(self):
for child in self.children:
def leaves(self):
for child in self.children:
for ch in self.children:
assert ch.parent is None, repr(ch)
ch.parent = self
for ch in self.children:
assert ch.parent is None, repr(ch)
ch.parent = self
+ self.invalidate_sibling_maps()
if prefix is not None:
self.prefix = prefix
if fixers_applied:
if prefix is not None:
self.prefix = prefix
if fixers_applied:
self.children[i].parent = None
self.children[i] = child
self.changed()
self.children[i].parent = None
self.children[i] = child
self.changed()
+ self.invalidate_sibling_maps()
def insert_child(self, i, child):
"""
def insert_child(self, i, child):
"""
child.parent = self
self.children.insert(i, child)
self.changed()
child.parent = self
self.children.insert(i, child)
self.changed()
+ self.invalidate_sibling_maps()
def append_child(self, child):
"""
def append_child(self, child):
"""
child.parent = self
self.children.append(child)
self.changed()
child.parent = self
self.children.append(child)
self.changed()
+ self.invalidate_sibling_maps()
+
+ def invalidate_sibling_maps(self):
+ self.prev_sibling_map = None
+ self.next_sibling_map = None
+
+ def update_sibling_maps(self):
+ self.prev_sibling_map = _prev = {}
+ self.next_sibling_map = _next = {}
+ previous = None
+ for current in self.children:
+ _prev[id(current)] = previous
+ _next[id(previous)] = current
+ previous = current
+ _next[id(current)] = None