mercurial/parsers.c
changeset 16665 e410be860393
parent 16664 5bc6edf71b39
child 16699 d947e1da1259
equal deleted inserted replaced
16664:5bc6edf71b39 16665:e410be860393
   564 
   564 
   565 	if (self->nt == NULL)
   565 	if (self->nt == NULL)
   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 
   573 	for (level = off = 0; level < maxlevel; level++) {
   573 	for (level = off = 0; level < maxlevel; level++) {
   574 		int k = getnybble(node, level);
   574 		int k = getnybble(node, level);
   793 	if (rev == -2)
   793 	if (rev == -2)
   794 		raise_revlog_error();
   794 		raise_revlog_error();
   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;
   801 	int nodelen, rev;
   872 	int nodelen, rev;
   802 
   873 
  1075 	 "clear the index caches"},
  1146 	 "clear the index caches"},
  1076 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
  1147 	{"get", (PyCFunction)index_m_get, METH_VARARGS,
  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 */
  1083 };
  1156 };
  1084 
  1157