##// END OF EJS Templates
revlog: speed up prefix matching against nodes...
Bryan O'Sullivan -
r16665:e410be86 default
parent child Browse files
Show More
@@ -566,7 +566,7 b' static int nt_find(indexObject *self, co'
566 return -2;
566 return -2;
567
567
568 if (hex)
568 if (hex)
569 maxlevel = nodelen > 40 ? 40 : nodelen;
569 maxlevel = nodelen > 40 ? 40 : (int)nodelen;
570 else
570 else
571 maxlevel = nodelen > 20 ? 40 : ((int)nodelen * 2);
571 maxlevel = nodelen > 20 ? 40 : ((int)nodelen * 2);
572
572
@@ -795,6 +795,77 b' static PyObject *index_getitem(indexObje'
795 return NULL;
795 return NULL;
796 }
796 }
797
797
798 static int nt_partialmatch(indexObject *self, const char *node,
799 Py_ssize_t nodelen)
800 {
801 int rev;
802
803 if (nt_init(self) == -1)
804 return -3;
805
806 if (self->ntrev > 0) {
807 /* ensure that the radix tree is fully populated */
808 for (rev = self->ntrev - 1; rev >= 0; rev--) {
809 const char *n = index_node(self, rev);
810 if (n == NULL)
811 return -2;
812 if (nt_insert(self, n, rev) == -1)
813 return -3;
814 }
815 self->ntrev = rev;
816 }
817
818 return nt_find(self, node, nodelen, 1);
819 }
820
821 static PyObject *index_partialmatch(indexObject *self, PyObject *args)
822 {
823 const char *fullnode;
824 int nodelen;
825 char *node;
826 int rev, i;
827
828 if (!PyArg_ParseTuple(args, "s#", &node, &nodelen))
829 return NULL;
830
831 if (nodelen < 4) {
832 PyErr_SetString(PyExc_ValueError, "key too short");
833 return NULL;
834 }
835
836 if (nodelen > 40)
837 nodelen = 40;
838
839 for (i = 0; i < nodelen; i++)
840 hexdigit(node, i);
841 if (PyErr_Occurred()) {
842 /* input contains non-hex characters */
843 PyErr_Clear();
844 Py_RETURN_NONE;
845 }
846
847 rev = nt_partialmatch(self, node, nodelen);
848
849 switch (rev) {
850 case -4:
851 raise_revlog_error();
852 case -3:
853 return NULL;
854 case -2:
855 Py_RETURN_NONE;
856 case -1:
857 return PyString_FromStringAndSize(nullid, 20);
858 }
859
860 fullnode = index_node(self, rev);
861 if (fullnode == NULL) {
862 PyErr_Format(PyExc_IndexError,
863 "could not access rev %d", rev);
864 return NULL;
865 }
866 return PyString_FromStringAndSize(fullnode, 20);
867 }
868
798 static PyObject *index_m_get(indexObject *self, PyObject *args)
869 static PyObject *index_m_get(indexObject *self, PyObject *args)
799 {
870 {
800 char *node;
871 char *node;
@@ -1077,6 +1148,8 b' static PyMethodDef index_methods[] = {'
1077 "get an index entry"},
1148 "get an index entry"},
1078 {"insert", (PyCFunction)index_insert, METH_VARARGS,
1149 {"insert", (PyCFunction)index_insert, METH_VARARGS,
1079 "insert an index entry"},
1150 "insert an index entry"},
1151 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
1152 "match a potentially ambiguous node ID"},
1080 {"stats", (PyCFunction)index_stats, METH_NOARGS,
1153 {"stats", (PyCFunction)index_stats, METH_NOARGS,
1081 "stats for the index"},
1154 "stats for the index"},
1082 {NULL} /* Sentinel */
1155 {NULL} /* Sentinel */
@@ -756,6 +756,15 b' class revlog(object):'
756 pass
756 pass
757
757
758 def _partialmatch(self, id):
758 def _partialmatch(self, id):
759 try:
760 return self.index.partialmatch(id)
761 except RevlogError:
762 # parsers.c radix tree lookup gave multiple matches
763 raise LookupError(id, self.indexfile, _("ambiguous identifier"))
764 except (AttributeError, ValueError):
765 # we are pure python, or key was too short to search radix tree
766 pass
767
759 if id in self._pcache:
768 if id in self._pcache:
760 return self._pcache[id]
769 return self._pcache[id]
761
770
General Comments 0
You need to be logged in to leave comments. Login now