##// END OF EJS Templates
revlog: use node tree (native code) for shortest() calculation...
Martin von Zweigbergk -
r37987:0304f224 default
parent child Browse files
Show More
@@ -713,7 +713,7 b' void dirs_module_init(PyObject *mod);'
713 void manifest_module_init(PyObject *mod);
713 void manifest_module_init(PyObject *mod);
714 void revlog_module_init(PyObject *mod);
714 void revlog_module_init(PyObject *mod);
715
715
716 static const int version = 4;
716 static const int version = 5;
717
717
718 static void module_init(PyObject *mod)
718 static void module_init(PyObject *mod)
719 {
719 {
@@ -1259,6 +1259,55 b' static int nt_partialmatch(indexObject *'
1259 return nt_find(self, node, nodelen, 1);
1259 return nt_find(self, node, nodelen, 1);
1260 }
1260 }
1261
1261
1262 /*
1263 * Find the length of the shortest unique prefix of node.
1264 *
1265 * Return values:
1266 *
1267 * -3: error (exception set)
1268 * -2: not found (no exception set)
1269 * rest: length of shortest prefix
1270 */
1271 static int nt_shortest(indexObject *self, const char *node)
1272 {
1273 int level, off;
1274
1275 if (nt_init(self) == -1)
1276 return -3;
1277 if (nt_populate(self) == -1)
1278 return -3;
1279
1280 for (level = off = 0; level < 40; level++) {
1281 int k, v;
1282 nodetree *n = &self->nt[off];
1283 k = nt_level(node, level);
1284 v = n->children[k];
1285 if (v < 0) {
1286 const char *n;
1287 v = -(v + 1);
1288 n = index_node(self, v);
1289 if (memcmp(node, n, 20) != 0)
1290 /*
1291 * Found a unique prefix, but it wasn't for the
1292 * requested node (i.e the requested node does
1293 * not exist).
1294 */
1295 return -2;
1296 return level + 1;
1297 }
1298 if (v == 0)
1299 return -2;
1300 off = v;
1301 }
1302 /*
1303 * The node was still not unique after 40 hex digits, so this won't
1304 * happen. Also, if we get here, then there's a programming error in
1305 * this file that made us insert a node longer than 40 hex digits.
1306 */
1307 PyErr_SetString(PyExc_Exception, "broken node tree");
1308 return -3;
1309 }
1310
1262 static PyObject *index_partialmatch(indexObject *self, PyObject *args)
1311 static PyObject *index_partialmatch(indexObject *self, PyObject *args)
1263 {
1312 {
1264 const char *fullnode;
1313 const char *fullnode;
@@ -1307,6 +1356,29 b' static PyObject *index_partialmatch(inde'
1307 return PyBytes_FromStringAndSize(fullnode, 20);
1356 return PyBytes_FromStringAndSize(fullnode, 20);
1308 }
1357 }
1309
1358
1359 static PyObject *index_shortest(indexObject *self, PyObject *args)
1360 {
1361 Py_ssize_t nodelen;
1362 PyObject *val;
1363 char *node;
1364 int length;
1365
1366 if (!PyArg_ParseTuple(args, "O", &val))
1367 return NULL;
1368 if (node_check(val, &node, &nodelen) == -1)
1369 return NULL;
1370
1371 self->ntlookups++;
1372 length = nt_shortest(self, node);
1373 if (length == -3)
1374 return NULL;
1375 if (length == -2) {
1376 raise_revlog_error();
1377 return NULL;
1378 }
1379 return PyInt_FromLong(length);
1380 }
1381
1310 static PyObject *index_m_get(indexObject *self, PyObject *args)
1382 static PyObject *index_m_get(indexObject *self, PyObject *args)
1311 {
1383 {
1312 Py_ssize_t nodelen;
1384 Py_ssize_t nodelen;
@@ -1995,6 +2067,8 b' static PyMethodDef index_methods[] = {'
1995 "insert an index entry"},
2067 "insert an index entry"},
1996 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
2068 {"partialmatch", (PyCFunction)index_partialmatch, METH_VARARGS,
1997 "match a potentially ambiguous node ID"},
2069 "match a potentially ambiguous node ID"},
2070 {"shortest", (PyCFunction)index_shortest, METH_VARARGS,
2071 "find length of shortest hex nodeid of a binary ID"},
1998 {"stats", (PyCFunction)index_stats, METH_NOARGS,
2072 {"stats", (PyCFunction)index_stats, METH_NOARGS,
1999 "stats for the index"},
2073 "stats for the index"},
2000 {NULL} /* Sentinel */
2074 {NULL} /* Sentinel */
@@ -69,7 +69,7 b' def _importfrom(pkgname, modname):'
69 (r'cext', r'bdiff'): 3,
69 (r'cext', r'bdiff'): 3,
70 (r'cext', r'mpatch'): 1,
70 (r'cext', r'mpatch'): 1,
71 (r'cext', r'osutil'): 4,
71 (r'cext', r'osutil'): 4,
72 (r'cext', r'parsers'): 4,
72 (r'cext', r'parsers'): 5,
73 }
73 }
74
74
75 # map import request to other package or module
75 # map import request to other package or module
@@ -1526,7 +1526,33 b' class revlog(object):'
1526 raise LookupError(node, self.indexfile, _('no node'))
1526 raise LookupError(node, self.indexfile, _('no node'))
1527 return not isrev(prefix)
1527 return not isrev(prefix)
1528
1528
1529 def maybewdir(prefix):
1530 return all(c == 'f' for c in prefix)
1531
1529 hexnode = hex(node)
1532 hexnode = hex(node)
1533
1534 def disambiguate(hexnode, minlength):
1535 for length in range(minlength, 41):
1536 prefix = hexnode[:length]
1537 if not isrev(prefix) and not maybewdir(prefix):
1538 return prefix
1539
1540 if not getattr(self, 'filteredrevs', None):
1541 try:
1542 length = max(self.index.shortest(node), minlength)
1543 return disambiguate(hexnode, length)
1544 except RevlogError:
1545 if node == wdirid:
1546 for length in range(minlength, 41):
1547 prefix = hexnode[:length]
1548 if isvalid(prefix):
1549 return prefix
1550 else:
1551 raise LookupError(node, self.indexfile, _('no node'))
1552 except AttributeError:
1553 # Fall through to pure code
1554 pass
1555
1530 shortest = hexnode
1556 shortest = hexnode
1531 startlength = max(6, minlength)
1557 startlength = max(6, minlength)
1532 length = startlength
1558 length = startlength
General Comments 0
You need to be logged in to leave comments. Login now