Mercurial > p > roundup > code
changeset 2239:c8a06e10e2c6
much faster anydbm filter(), but it breaks most filtering tests
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 26 Apr 2004 00:46:34 +0000 |
| parents | df0444e39bc3 |
| children | ad4b717e12b9 |
| files | roundup/backends/back_anydbm.py |
| diffstat | 1 files changed, 41 insertions(+), 94 deletions(-) [+] |
line wrap: on
line diff
--- a/roundup/backends/back_anydbm.py Mon Apr 26 00:44:30 2004 +0000 +++ b/roundup/backends/back_anydbm.py Mon Apr 26 00:46:34 2004 +0000 @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -#$Id: back_anydbm.py,v 1.142 2004-04-25 22:19:15 richard Exp $ +#$Id: back_anydbm.py,v 1.143 2004-04-26 00:46:34 richard Exp $ '''This module defines a backend that saves the hyperdatabase in a database chosen by anydbm. It is guaranteed to always be available in python versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several @@ -1662,7 +1662,7 @@ filterspec = l # now, find all the nodes that are active and pass filtering - l = [] + matches = [] cldb = self.db.getclassdb(cn) try: # TODO: only full-scan once (use items()) @@ -1724,123 +1724,70 @@ if node[k] != v: break else: - l.append((nodeid, node)) + matches.append([nodeid, node]) finally: cldb.close() - l.sort() # filter based on full text search if search_matches is not None: k = [] - for v in l: + for v in matches: if search_matches.has_key(v[0]): k.append(v) - l = k + matches = k - # now, sort the result - def sortfun(a, b, sort=sort, group=group, properties=self.getprops(), - db = self.db, cl=self): - a_id, an = a - b_id, bn = b - # sort by group and then sort - for dir, prop in group, sort: - if dir is None or prop is None: continue - - # sorting is class-specific - propclass = properties[prop] - + # add sorting information to the match entries + directions = [] + for dir, prop in sort, group: + if dir is None or prop is None: + continue + directions.append(dir) + propclass = props[prop] + for entry in matches: + itemid = entry[-2] + item = entry[-1] # handle the properties that might be "faked" # also, handle possible missing properties try: - if not an.has_key(prop): - an[prop] = cl.get(a_id, prop) - av = an[prop] - except KeyError: - # the node doesn't have a value for this property - if isinstance(propclass, Multilink): av = [] - else: av = '' - try: - if not bn.has_key(prop): - bn[prop] = cl.get(b_id, prop) - bv = bn[prop] + v = self.get(itemid, prop) except KeyError: # the node doesn't have a value for this property - if isinstance(propclass, Multilink): bv = [] - else: bv = '' + if isinstance(propclass, Multilink): v = [] + else: v = None + s.append((v, itemid, item)) + continue - # String and Date values are sorted in the natural way if isinstance(propclass, String): - # clean up the strings - if av and av[0] in string.uppercase: - av = av.lower() - if bv and bv[0] in string.uppercase: - bv = bv.lower() - if (isinstance(propclass, String) or - isinstance(propclass, Date)): # it might be a string that's really an integer - try: - av = int(av) - bv = int(bv) - except: - pass - if dir == '+': - r = cmp(av, bv) - if r != 0: return r - elif dir == '-': - r = cmp(bv, av) - if r != 0: return r - - # Link properties are sorted according to the value of - # the "order" property on the linked nodes if it is - # present; or otherwise on the key string of the linked - # nodes; or finally on the node ids. + try: tv = int(v) + except: v = v.lower() + else: v = tv elif isinstance(propclass, Link): - link = db.classes[propclass.classname] - if av is None and bv is not None: return -1 - if av is not None and bv is None: return 1 - if av is None and bv is None: continue + link = self.db.classes[propclass.classname] if link.getprops().has_key('order'): - if dir == '+': - r = cmp(link.get(av, 'order'), - link.get(bv, 'order')) - if r != 0: return r - elif dir == '-': - r = cmp(link.get(bv, 'order'), - link.get(av, 'order')) - if r != 0: return r + v = link.get(v, 'order') elif link.getkey(): key = link.getkey() - if dir == '+': - r = cmp(link.get(av, key), link.get(bv, key)) - if r != 0: return r - elif dir == '-': - r = cmp(link.get(bv, key), link.get(av, key)) - if r != 0: return r - else: - if dir == '+': - r = cmp(av, bv) - if r != 0: return r - elif dir == '-': - r = cmp(bv, av) - if r != 0: return r + v = link.get(v, key) + entry.insert(0, v) - else: - # all other types just compare - if dir == '+': - r = cmp(av, bv) - elif dir == '-': - r = cmp(bv, av) - if r != 0: return r - - # end for dir, prop in sort, group: - # if all else fails, compare the ids - return cmp(a[0], b[0]) + if directions: + # sort using the first one or two columns + def sortfun(a, b, directions=directions, n=range(len(directions))): + for i in n: + if a[i] == b[i]: continue + if directions[i] == '-': + return cmp(a[i],b[i]) + else: + return cmp(b[i],a[i]) + return 0 + matches.sort(sortfun) - l.sort(sortfun) - l = [i[0] for i in l] + # pull the id out of the individual entries + matches = [entry[-2] for entry in matches] if __debug__: self.db.stats['filtering'] += (time.time() - start_t) - return l + return matches def count(self): '''Get the number of nodes in this class.
