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

Roundup Issue Tracker: http://roundup-tracker.org/