Skip to content

Commit 1cb657d

Browse files
author
Richard Jones
committed
much faster anydbm filter(), but it breaks most filtering tests
1 parent f086317 commit 1cb657d

File tree

1 file changed

+41
-94
lines changed

1 file changed

+41
-94
lines changed

roundup/backends/back_anydbm.py

Lines changed: 41 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
#$Id: back_anydbm.py,v 1.142 2004-04-25 22:19:15 richard Exp $
18+
#$Id: back_anydbm.py,v 1.143 2004-04-26 00:46:34 richard Exp $
1919
'''This module defines a backend that saves the hyperdatabase in a
2020
database chosen by anydbm. It is guaranteed to always be available in python
2121
versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
@@ -1662,7 +1662,7 @@ def filter(self, search_matches, filterspec, sort=(None,None),
16621662
filterspec = l
16631663

16641664
# now, find all the nodes that are active and pass filtering
1665-
l = []
1665+
matches = []
16661666
cldb = self.db.getclassdb(cn)
16671667
try:
16681668
# TODO: only full-scan once (use items())
@@ -1724,123 +1724,70 @@ def filter(self, search_matches, filterspec, sort=(None,None),
17241724
if node[k] != v:
17251725
break
17261726
else:
1727-
l.append((nodeid, node))
1727+
matches.append([nodeid, node])
17281728
finally:
17291729
cldb.close()
1730-
l.sort()
17311730

17321731
# filter based on full text search
17331732
if search_matches is not None:
17341733
k = []
1735-
for v in l:
1734+
for v in matches:
17361735
if search_matches.has_key(v[0]):
17371736
k.append(v)
1738-
l = k
1739-
1740-
# now, sort the result
1741-
def sortfun(a, b, sort=sort, group=group, properties=self.getprops(),
1742-
db = self.db, cl=self):
1743-
a_id, an = a
1744-
b_id, bn = b
1745-
# sort by group and then sort
1746-
for dir, prop in group, sort:
1747-
if dir is None or prop is None: continue
1748-
1749-
# sorting is class-specific
1750-
propclass = properties[prop]
1737+
matches = k
17511738

1739+
# add sorting information to the match entries
1740+
directions = []
1741+
for dir, prop in sort, group:
1742+
if dir is None or prop is None:
1743+
continue
1744+
directions.append(dir)
1745+
propclass = props[prop]
1746+
for entry in matches:
1747+
itemid = entry[-2]
1748+
item = entry[-1]
17521749
# handle the properties that might be "faked"
17531750
# also, handle possible missing properties
17541751
try:
1755-
if not an.has_key(prop):
1756-
an[prop] = cl.get(a_id, prop)
1757-
av = an[prop]
1752+
v = self.get(itemid, prop)
17581753
except KeyError:
17591754
# the node doesn't have a value for this property
1760-
if isinstance(propclass, Multilink): av = []
1761-
else: av = ''
1762-
try:
1763-
if not bn.has_key(prop):
1764-
bn[prop] = cl.get(b_id, prop)
1765-
bv = bn[prop]
1766-
except KeyError:
1767-
# the node doesn't have a value for this property
1768-
if isinstance(propclass, Multilink): bv = []
1769-
else: bv = ''
1755+
if isinstance(propclass, Multilink): v = []
1756+
else: v = None
1757+
s.append((v, itemid, item))
1758+
continue
17701759

1771-
# String and Date values are sorted in the natural way
17721760
if isinstance(propclass, String):
1773-
# clean up the strings
1774-
if av and av[0] in string.uppercase:
1775-
av = av.lower()
1776-
if bv and bv[0] in string.uppercase:
1777-
bv = bv.lower()
1778-
if (isinstance(propclass, String) or
1779-
isinstance(propclass, Date)):
17801761
# it might be a string that's really an integer
1781-
try:
1782-
av = int(av)
1783-
bv = int(bv)
1784-
except:
1785-
pass
1786-
if dir == '+':
1787-
r = cmp(av, bv)
1788-
if r != 0: return r
1789-
elif dir == '-':
1790-
r = cmp(bv, av)
1791-
if r != 0: return r
1792-
1793-
# Link properties are sorted according to the value of
1794-
# the "order" property on the linked nodes if it is
1795-
# present; or otherwise on the key string of the linked
1796-
# nodes; or finally on the node ids.
1762+
try: tv = int(v)
1763+
except: v = v.lower()
1764+
else: v = tv
17971765
elif isinstance(propclass, Link):
1798-
link = db.classes[propclass.classname]
1799-
if av is None and bv is not None: return -1
1800-
if av is not None and bv is None: return 1
1801-
if av is None and bv is None: continue
1766+
link = self.db.classes[propclass.classname]
18021767
if link.getprops().has_key('order'):
1803-
if dir == '+':
1804-
r = cmp(link.get(av, 'order'),
1805-
link.get(bv, 'order'))
1806-
if r != 0: return r
1807-
elif dir == '-':
1808-
r = cmp(link.get(bv, 'order'),
1809-
link.get(av, 'order'))
1810-
if r != 0: return r
1768+
v = link.get(v, 'order')
18111769
elif link.getkey():
18121770
key = link.getkey()
1813-
if dir == '+':
1814-
r = cmp(link.get(av, key), link.get(bv, key))
1815-
if r != 0: return r
1816-
elif dir == '-':
1817-
r = cmp(link.get(bv, key), link.get(av, key))
1818-
if r != 0: return r
1771+
v = link.get(v, key)
1772+
entry.insert(0, v)
1773+
1774+
if directions:
1775+
# sort using the first one or two columns
1776+
def sortfun(a, b, directions=directions, n=range(len(directions))):
1777+
for i in n:
1778+
if a[i] == b[i]: continue
1779+
if directions[i] == '-':
1780+
return cmp(a[i],b[i])
18191781
else:
1820-
if dir == '+':
1821-
r = cmp(av, bv)
1822-
if r != 0: return r
1823-
elif dir == '-':
1824-
r = cmp(bv, av)
1825-
if r != 0: return r
1782+
return cmp(b[i],a[i])
1783+
return 0
1784+
matches.sort(sortfun)
18261785

1827-
else:
1828-
# all other types just compare
1829-
if dir == '+':
1830-
r = cmp(av, bv)
1831-
elif dir == '-':
1832-
r = cmp(bv, av)
1833-
if r != 0: return r
1834-
1835-
# end for dir, prop in sort, group:
1836-
# if all else fails, compare the ids
1837-
return cmp(a[0], b[0])
1838-
1839-
l.sort(sortfun)
1840-
l = [i[0] for i in l]
1786+
# pull the id out of the individual entries
1787+
matches = [entry[-2] for entry in matches]
18411788
if __debug__:
18421789
self.db.stats['filtering'] += (time.time() - start_t)
1843-
return l
1790+
return matches
18441791

18451792
def count(self):
18461793
'''Get the number of nodes in this class.

0 commit comments

Comments
 (0)