Mercurial > p > roundup > code
comparison roundup/hyperdb.py @ 834:568eed5fb4fd
Optimize Class.find so that the propspec can contain a set of ids to match.
This is used by indexer.search so it can do just one find for all the
index matches.
This was already confusing code, but for common terms (lots of index matches),
it is enormously faster.
| author | Gordon B. McMillan <gmcm@users.sourceforge.net> |
|---|---|
| date | Tue, 09 Jul 2002 21:53:38 +0000 |
| parents | 0779ea9f1f18 |
| children | bf55b2b800b9 |
comparison
equal
deleted
inserted
replaced
| 833:b80aaedba3db | 834:568eed5fb4fd |
|---|---|
| 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" | 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" |
| 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, | 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, |
| 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
| 17 # | 17 # |
| 18 # $Id: hyperdb.py,v 1.71 2002-07-09 03:02:52 richard Exp $ | 18 # $Id: hyperdb.py,v 1.72 2002-07-09 21:53:38 gmcm Exp $ |
| 19 | 19 |
| 20 __doc__ = """ | 20 __doc__ = """ |
| 21 Hyperdatabase implementation, especially field types. | 21 Hyperdatabase implementation, especially field types. |
| 22 """ | 22 """ |
| 23 | 23 |
| 783 return nodeid | 783 return nodeid |
| 784 raise KeyError, keyvalue | 784 raise KeyError, keyvalue |
| 785 | 785 |
| 786 # XXX: change from spec - allows multiple props to match | 786 # XXX: change from spec - allows multiple props to match |
| 787 def find(self, **propspec): | 787 def find(self, **propspec): |
| 788 """Get the ids of nodes in this class which link to a given node. | 788 """Get the ids of nodes in this class which link to the given nodes. |
| 789 | 789 |
| 790 'propspec' consists of keyword args propname=nodeid | 790 'propspec' consists of keyword args propname={nodeid:1,} |
| 791 'propname' must be the name of a property in this class, or a | 791 'propname' must be the name of a property in this class, or a |
| 792 KeyError is raised. That property must be a Link or Multilink | 792 KeyError is raised. That property must be a Link or Multilink |
| 793 property, or a TypeError is raised. | 793 property, or a TypeError is raised. |
| 794 | 794 |
| 795 'nodeid' must be the id of an existing node in the class linked | 795 Any node in this class whose 'propname' property links to any of the |
| 796 to by the given property, or an IndexError is raised. | 796 nodeids will be returned. Used by the full text indexing, which knows |
| 797 that "foo" occurs in msg1, msg3 and file7, so we have hits on these issues: | |
| 798 db.issue.find(messages={'1':1,'3':1}, files={'7':1}) | |
| 797 """ | 799 """ |
| 798 propspec = propspec.items() | 800 propspec = propspec.items() |
| 799 for propname, nodeid in propspec: | 801 for propname, nodeids in propspec: |
| 800 # check the prop is OK | 802 # check the prop is OK |
| 801 prop = self.properties[propname] | 803 prop = self.properties[propname] |
| 802 if not isinstance(prop, Link) and not isinstance(prop, Multilink): | 804 if not isinstance(prop, Link) and not isinstance(prop, Multilink): |
| 803 raise TypeError, "'%s' not a Link/Multilink property"%propname | 805 raise TypeError, "'%s' not a Link/Multilink property"%propname |
| 804 if not self.db.hasnode(prop.classname, nodeid): | 806 #XXX edit is expensive and of questionable use |
| 805 raise ValueError, '%s has no node %s'%(prop.classname, nodeid) | 807 #for nodeid in nodeids: |
| 808 # if not self.db.hasnode(prop.classname, nodeid): | |
| 809 # raise ValueError, '%s has no node %s'%(prop.classname, nodeid) | |
| 806 | 810 |
| 807 # ok, now do the find | 811 # ok, now do the find |
| 808 cldb = self.db.getclassdb(self.classname) | 812 cldb = self.db.getclassdb(self.classname) |
| 809 l = [] | 813 l = [] |
| 810 for id in self.db.getnodeids(self.classname, db=cldb): | 814 for id in self.db.getnodeids(self.classname, db=cldb): |
| 811 node = self.db.getnode(self.classname, id, db=cldb) | 815 node = self.db.getnode(self.classname, id, db=cldb) |
| 812 if node.has_key(self.db.RETIRED_FLAG): | 816 if node.has_key(self.db.RETIRED_FLAG): |
| 813 continue | 817 continue |
| 814 for propname, nodeid in propspec: | 818 for propname, nodeids in propspec: |
| 815 # can't test if the node doesn't have this property | 819 # can't test if the node doesn't have this property |
| 816 if not node.has_key(propname): | 820 if not node.has_key(propname): |
| 817 continue | 821 continue |
| 822 if type(nodeids) is type(''): | |
| 823 nodeids = {nodeids:1} | |
| 818 prop = self.properties[propname] | 824 prop = self.properties[propname] |
| 819 property = node[propname] | 825 value = node[propname] |
| 820 if isinstance(prop, Link) and nodeid == property: | 826 if isinstance(prop, Link) and nodeids.has_key(value): |
| 821 l.append(id) | 827 l.append(id) |
| 822 elif isinstance(prop, Multilink) and nodeid in property: | 828 break |
| 823 l.append(id) | 829 elif isinstance(prop, Multilink): |
| 830 hit = 0 | |
| 831 for v in value: | |
| 832 if nodeids.has_key(v): | |
| 833 l.append(id) | |
| 834 hit = 1 | |
| 835 break | |
| 836 if hit: | |
| 837 break | |
| 824 return l | 838 return l |
| 825 | 839 |
| 826 def stringFind(self, **requirements): | 840 def stringFind(self, **requirements): |
| 827 """Locate a particular node by matching a set of its String | 841 """Locate a particular node by matching a set of its String |
| 828 properties in a caseless search. | 842 properties in a caseless search. |
| 1183 cl.create(name=options[i], order=i) | 1197 cl.create(name=options[i], order=i) |
| 1184 return hyperdb.Link(name) | 1198 return hyperdb.Link(name) |
| 1185 | 1199 |
| 1186 # | 1200 # |
| 1187 # $Log: not supported by cvs2svn $ | 1201 # $Log: not supported by cvs2svn $ |
| 1202 # Revision 1.71 2002/07/09 03:02:52 richard | |
| 1203 # More indexer work: | |
| 1204 # - all String properties may now be indexed too. Currently there's a bit of | |
| 1205 # "issue" specific code in the actual searching which needs to be | |
| 1206 # addressed. In a nutshell: | |
| 1207 # + pass 'indexme="yes"' as a String() property initialisation arg, eg: | |
| 1208 # file = FileClass(db, "file", name=String(), type=String(), | |
| 1209 # comment=String(indexme="yes")) | |
| 1210 # + the comment will then be indexed and be searchable, with the results | |
| 1211 # related back to the issue that the file is linked to | |
| 1212 # - as a result of this work, the FileClass has a default MIME type that may | |
| 1213 # be overridden in a subclass, or by the use of a "type" property as is | |
| 1214 # done in the default templates. | |
| 1215 # - the regeneration of the indexes (if necessary) is done once the schema is | |
| 1216 # set up in the dbinit. | |
| 1217 # | |
| 1188 # Revision 1.70 2002/06/27 12:06:20 gmcm | 1218 # Revision 1.70 2002/06/27 12:06:20 gmcm |
| 1189 # Improve an error message. | 1219 # Improve an error message. |
| 1190 # | 1220 # |
| 1191 # Revision 1.69 2002/06/17 23:15:29 richard | 1221 # Revision 1.69 2002/06/17 23:15:29 richard |
| 1192 # Can debug to stdout now | 1222 # Can debug to stdout now |
