Show More
@@ -42,7 +42,6 b' typedef struct {' | |||
|
42 | 42 | * Zero is empty |
|
43 | 43 | */ |
|
44 | 44 | typedef struct { |
|
45 | PyObject_HEAD | |
|
46 | 45 | indexObject *index; |
|
47 | 46 | nodetreenode *nodes; |
|
48 | 47 | unsigned length; /* # nodes in use */ |
@@ -51,6 +50,11 b' typedef struct {' | |||
|
51 | 50 | int splits; /* # splits performed */ |
|
52 | 51 | } nodetree; |
|
53 | 52 | |
|
53 | typedef struct { | |
|
54 | PyObject_HEAD | |
|
55 | nodetree nt; | |
|
56 | } nodetreeObject; | |
|
57 | ||
|
54 | 58 | /* |
|
55 | 59 | * This class has two behaviors. |
|
56 | 60 | * |
@@ -75,7 +79,8 b' struct indexObjectStruct {' | |||
|
75 | 79 | PyObject *added; /* populated on demand */ |
|
76 | 80 | PyObject *headrevs; /* cache, invalidated on changes */ |
|
77 | 81 | PyObject *filteredrevs;/* filtered revs set */ |
|
78 |
nodetree |
|
|
82 | nodetree nt; /* base-16 trie */ | |
|
83 | int ntinitialized; /* 0 or 1 */ | |
|
79 | 84 | int ntrev; /* last rev scanned */ |
|
80 | 85 | int ntlookups; /* # lookups */ |
|
81 | 86 | int ntmisses; /* # lookups that miss the cache */ |
@@ -333,8 +338,8 b' static PyObject *index_append(indexObjec' | |||
|
333 | 338 | if (PyList_Append(self->added, obj) == -1) |
|
334 | 339 | return NULL; |
|
335 | 340 | |
|
336 | if (self->nt) | |
|
337 | nt_insert(self->nt, node, (int)len); | |
|
341 | if (self->ntinitialized) | |
|
342 | nt_insert(&self->nt, node, (int)len); | |
|
338 | 343 | |
|
339 | 344 | Py_CLEAR(self->headrevs); |
|
340 | 345 | Py_RETURN_NONE; |
@@ -374,11 +379,11 b' static PyObject *index_stats(indexObject' | |||
|
374 | 379 | istat(ntlookups, "node trie lookups"); |
|
375 | 380 | istat(ntmisses, "node trie misses"); |
|
376 | 381 | istat(ntrev, "node trie last rev scanned"); |
|
377 | if (self->nt) { | |
|
378 |
istat(nt |
|
|
379 |
istat(nt |
|
|
380 |
istat(nt |
|
|
381 |
istat(nt |
|
|
382 | if (self->ntinitialized) { | |
|
383 | istat(nt.capacity, "node trie capacity"); | |
|
384 | istat(nt.depth, "node trie depth"); | |
|
385 | istat(nt.length, "node trie count"); | |
|
386 | istat(nt.splits, "node trie splits"); | |
|
382 | 387 | } |
|
383 | 388 | |
|
384 | 389 | #undef istat |
@@ -1087,20 +1092,20 b' static int nt_insert(nodetree *self, con' | |||
|
1087 | 1092 | return -1; |
|
1088 | 1093 | } |
|
1089 | 1094 | |
|
1090 |
static PyObject *nt_insert |
|
|
1095 | static PyObject *ntobj_insert(nodetreeObject *self, PyObject *args) | |
|
1091 | 1096 | { |
|
1092 | 1097 | Py_ssize_t rev; |
|
1093 | 1098 | const char *node; |
|
1094 | 1099 | Py_ssize_t length; |
|
1095 | 1100 | if (!PyArg_ParseTuple(args, "n", &rev)) |
|
1096 | 1101 | return NULL; |
|
1097 | length = index_length(self->index); | |
|
1102 | length = index_length(self->nt.index); | |
|
1098 | 1103 | if (rev < 0 || rev >= length) { |
|
1099 | 1104 | PyErr_SetString(PyExc_ValueError, "revlog index out of range"); |
|
1100 | 1105 | return NULL; |
|
1101 | 1106 | } |
|
1102 | node = index_node_existing(self->index, rev); | |
|
1103 | if (nt_insert(self, node, (int)rev) == -1) | |
|
1107 | node = index_node_existing(self->nt.index, rev); | |
|
1108 | if (nt_insert(&self->nt, node, (int)rev) == -1) | |
|
1104 | 1109 | return NULL; |
|
1105 | 1110 | Py_RETURN_NONE; |
|
1106 | 1111 | } |
@@ -1117,7 +1122,6 b' static int nt_init(nodetree *self, index' | |||
|
1117 | 1122 | self->nodes = NULL; |
|
1118 | 1123 | |
|
1119 | 1124 | self->index = index; |
|
1120 | Py_INCREF(index); | |
|
1121 | 1125 | /* The input capacity is in terms of revisions, while the field is in |
|
1122 | 1126 | * terms of nodetree nodes. */ |
|
1123 | 1127 | self->capacity = (capacity < 4 ? 4 : capacity / 2); |
@@ -1138,13 +1142,14 b' static int nt_init(nodetree *self, index' | |||
|
1138 | 1142 | |
|
1139 | 1143 | static PyTypeObject indexType; |
|
1140 | 1144 | |
|
1141 |
static int nt_init |
|
|
1145 | static int ntobj_init(nodetreeObject *self, PyObject *args) | |
|
1142 | 1146 | { |
|
1143 | 1147 | PyObject *index; |
|
1144 | 1148 | unsigned capacity; |
|
1145 | 1149 | if (!PyArg_ParseTuple(args, "O!I", &indexType, &index, &capacity)) |
|
1146 | 1150 | return -1; |
|
1147 | return nt_init(self, (indexObject*)index, capacity); | |
|
1151 | Py_INCREF(index); | |
|
1152 | return nt_init(&self->nt, (indexObject*)index, capacity); | |
|
1148 | 1153 | } |
|
1149 | 1154 | |
|
1150 | 1155 | static int nt_partialmatch(nodetree *self, const char *node, |
@@ -1199,7 +1204,7 b' static int nt_shortest(nodetree *self, c' | |||
|
1199 | 1204 | return -3; |
|
1200 | 1205 | } |
|
1201 | 1206 | |
|
1202 |
static PyObject *nt_shortest |
|
|
1207 | static PyObject *ntobj_shortest(nodetreeObject *self, PyObject *args) | |
|
1203 | 1208 | { |
|
1204 | 1209 | PyObject *val; |
|
1205 | 1210 | char *node; |
@@ -1210,7 +1215,7 b' static PyObject *nt_shortest_py(nodetree' | |||
|
1210 | 1215 | if (node_check(val, &node) == -1) |
|
1211 | 1216 | return NULL; |
|
1212 | 1217 | |
|
1213 | length = nt_shortest(self, node); | |
|
1218 | length = nt_shortest(&self->nt, node); | |
|
1214 | 1219 | if (length == -3) |
|
1215 | 1220 | return NULL; |
|
1216 | 1221 | if (length == -2) { |
@@ -1222,16 +1227,21 b' static PyObject *nt_shortest_py(nodetree' | |||
|
1222 | 1227 | |
|
1223 | 1228 | static void nt_dealloc(nodetree *self) |
|
1224 | 1229 | { |
|
1225 | Py_XDECREF(self->index); | |
|
1226 | 1230 | free(self->nodes); |
|
1227 | 1231 | self->nodes = NULL; |
|
1232 | } | |
|
1233 | ||
|
1234 | static void ntobj_dealloc(nodetreeObject *self) | |
|
1235 | { | |
|
1236 | Py_XDECREF(self->nt.index); | |
|
1237 | nt_dealloc(&self->nt); | |
|
1228 | 1238 | PyObject_Del(self); |
|
1229 | 1239 | } |
|
1230 | 1240 | |
|
1231 | static PyMethodDef nt_methods[] = { | |
|
1232 |
{"insert", (PyCFunction)nt_insert |
|
|
1241 | static PyMethodDef ntobj_methods[] = { | |
|
1242 | {"insert", (PyCFunction)ntobj_insert, METH_VARARGS, | |
|
1233 | 1243 | "insert an index entry"}, |
|
1234 |
{"shortest", (PyCFunction)nt_shortest |
|
|
1244 | {"shortest", (PyCFunction)ntobj_shortest, METH_VARARGS, | |
|
1235 | 1245 | "find length of shortest hex nodeid of a binary ID"}, |
|
1236 | 1246 | {NULL} /* Sentinel */ |
|
1237 | 1247 | }; |
@@ -1241,7 +1251,7 b' static PyTypeObject nodetreeType = {' | |||
|
1241 | 1251 | "parsers.nodetree", /* tp_name */ |
|
1242 | 1252 | sizeof(nodetree) , /* tp_basicsize */ |
|
1243 | 1253 | 0, /* tp_itemsize */ |
|
1244 |
(destructor)nt_dealloc, |
|
|
1254 | (destructor)ntobj_dealloc, /* tp_dealloc */ | |
|
1245 | 1255 | 0, /* tp_print */ |
|
1246 | 1256 | 0, /* tp_getattr */ |
|
1247 | 1257 | 0, /* tp_setattr */ |
@@ -1264,7 +1274,7 b' static PyTypeObject nodetreeType = {' | |||
|
1264 | 1274 | 0, /* tp_weaklistoffset */ |
|
1265 | 1275 | 0, /* tp_iter */ |
|
1266 | 1276 | 0, /* tp_iternext */ |
|
1267 |
nt_methods, |
|
|
1277 | ntobj_methods, /* tp_methods */ | |
|
1268 | 1278 | 0, /* tp_members */ |
|
1269 | 1279 | 0, /* tp_getset */ |
|
1270 | 1280 | 0, /* tp_base */ |
@@ -1272,27 +1282,22 b' static PyTypeObject nodetreeType = {' | |||
|
1272 | 1282 | 0, /* tp_descr_get */ |
|
1273 | 1283 | 0, /* tp_descr_set */ |
|
1274 | 1284 | 0, /* tp_dictoffset */ |
|
1275 |
(initproc)nt_init |
|
|
1285 | (initproc)ntobj_init, /* tp_init */ | |
|
1276 | 1286 | 0, /* tp_alloc */ |
|
1277 | 1287 | }; |
|
1278 | 1288 | |
|
1279 | 1289 | static int index_init_nt(indexObject *self) |
|
1280 | 1290 | { |
|
1281 |
if (self->nt |
|
|
1282 | self->nt = PyObject_New(nodetree, &nodetreeType); | |
|
1283 | if (self->nt == NULL) { | |
|
1291 | if (!self->ntinitialized) { | |
|
1292 | if (nt_init(&self->nt, self, (int)self->raw_length) == -1) { | |
|
1293 | nt_dealloc(&self->nt); | |
|
1284 | 1294 | return -1; |
|
1285 | 1295 | } |
|
1286 |
if (nt_in |
|
|
1287 | nt_dealloc(self->nt); | |
|
1288 | self->nt = NULL; | |
|
1296 | if (nt_insert(&self->nt, nullid, -1) == -1) { | |
|
1297 | nt_dealloc(&self->nt); | |
|
1289 | 1298 | return -1; |
|
1290 | 1299 | } |
|
1291 | if (nt_insert(self->nt, nullid, -1) == -1) { | |
|
1292 | nt_dealloc(self->nt); | |
|
1293 | self->nt = NULL; | |
|
1294 | return -1; | |
|
1295 | } | |
|
1300 | self->ntinitialized = 1; | |
|
1296 | 1301 | self->ntrev = (int)index_length(self); |
|
1297 | 1302 | self->ntlookups = 1; |
|
1298 | 1303 | self->ntmisses = 0; |
@@ -1316,7 +1321,7 b' static int index_find_node(indexObject *' | |||
|
1316 | 1321 | return -3; |
|
1317 | 1322 | |
|
1318 | 1323 | self->ntlookups++; |
|
1319 | rev = nt_find(self->nt, node, nodelen, 0); | |
|
1324 | rev = nt_find(&self->nt, node, nodelen, 0); | |
|
1320 | 1325 | if (rev >= -1) |
|
1321 | 1326 | return rev; |
|
1322 | 1327 | |
@@ -1335,7 +1340,7 b' static int index_find_node(indexObject *' | |||
|
1335 | 1340 | if (n == NULL) |
|
1336 | 1341 | return -3; |
|
1337 | 1342 | if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) { |
|
1338 | if (nt_insert(self->nt, n, rev) == -1) | |
|
1343 | if (nt_insert(&self->nt, n, rev) == -1) | |
|
1339 | 1344 | return -3; |
|
1340 | 1345 | break; |
|
1341 | 1346 | } |
@@ -1345,7 +1350,7 b' static int index_find_node(indexObject *' | |||
|
1345 | 1350 | const char *n = index_node_existing(self, rev); |
|
1346 | 1351 | if (n == NULL) |
|
1347 | 1352 | return -3; |
|
1348 | if (nt_insert(self->nt, n, rev) == -1) { | |
|
1353 | if (nt_insert(&self->nt, n, rev) == -1) { | |
|
1349 | 1354 | self->ntrev = rev + 1; |
|
1350 | 1355 | return -3; |
|
1351 | 1356 | } |
@@ -1389,7 +1394,7 b' static int index_populate_nt(indexObject' | |||
|
1389 | 1394 | const char *n = index_node_existing(self, rev); |
|
1390 | 1395 | if (n == NULL) |
|
1391 | 1396 | return -1; |
|
1392 | if (nt_insert(self->nt, n, rev) == -1) | |
|
1397 | if (nt_insert(&self->nt, n, rev) == -1) | |
|
1393 | 1398 | return -1; |
|
1394 | 1399 | } |
|
1395 | 1400 | self->ntrev = -1; |
@@ -1429,7 +1434,7 b' static PyObject *index_partialmatch(inde' | |||
|
1429 | 1434 | return NULL; |
|
1430 | 1435 | if (index_populate_nt(self) == -1) |
|
1431 | 1436 | return NULL; |
|
1432 | rev = nt_partialmatch(self->nt, node, nodelen); | |
|
1437 | rev = nt_partialmatch(&self->nt, node, nodelen); | |
|
1433 | 1438 | |
|
1434 | 1439 | switch (rev) { |
|
1435 | 1440 | case -4: |
@@ -1464,7 +1469,7 b' static PyObject *index_shortest(indexObj' | |||
|
1464 | 1469 | return NULL; |
|
1465 | 1470 | if (index_populate_nt(self) == -1) |
|
1466 | 1471 | return NULL; |
|
1467 | length = nt_shortest(self->nt, node); | |
|
1472 | length = nt_shortest(&self->nt, node); | |
|
1468 | 1473 | if (length == -3) |
|
1469 | 1474 | return NULL; |
|
1470 | 1475 | if (length == -2) { |
@@ -1886,7 +1891,7 b' static void index_invalidate_added(index' | |||
|
1886 | 1891 | PyObject *tuple = PyList_GET_ITEM(self->added, i); |
|
1887 | 1892 | PyObject *node = PyTuple_GET_ITEM(tuple, 7); |
|
1888 | 1893 | |
|
1889 | nt_delete_node(self->nt, PyBytes_AS_STRING(node)); | |
|
1894 | nt_delete_node(&self->nt, PyBytes_AS_STRING(node)); | |
|
1890 | 1895 | } |
|
1891 | 1896 | |
|
1892 | 1897 | if (start == 0) |
@@ -1937,7 +1942,7 b' static int index_slice_del(indexObject *' | |||
|
1937 | 1942 | } |
|
1938 | 1943 | |
|
1939 | 1944 | if (start < self->length) { |
|
1940 | if (self->nt) { | |
|
1945 | if (self->ntinitialized) { | |
|
1941 | 1946 | Py_ssize_t i; |
|
1942 | 1947 | |
|
1943 | 1948 | for (i = start + 1; i < self->length; i++) { |
@@ -1945,7 +1950,7 b' static int index_slice_del(indexObject *' | |||
|
1945 | 1950 | if (node == NULL) |
|
1946 | 1951 | return -1; |
|
1947 | 1952 | |
|
1948 | nt_delete_node(self->nt, node); | |
|
1953 | nt_delete_node(&self->nt, node); | |
|
1949 | 1954 | } |
|
1950 | 1955 | if (self->added) |
|
1951 | 1956 | index_invalidate_added(self, 0); |
@@ -1964,7 +1969,7 b' static int index_slice_del(indexObject *' | |||
|
1964 | 1969 | goto done; |
|
1965 | 1970 | } |
|
1966 | 1971 | |
|
1967 | if (self->nt) { | |
|
1972 | if (self->ntinitialized) { | |
|
1968 | 1973 | index_invalidate_added(self, start - self->length); |
|
1969 | 1974 | if (self->ntrev > start) |
|
1970 | 1975 | self->ntrev = (int)start; |
@@ -1997,7 +2002,7 b' static int index_assign_subscript(indexO' | |||
|
1997 | 2002 | return -1; |
|
1998 | 2003 | |
|
1999 | 2004 | if (value == NULL) |
|
2000 | return self->nt ? nt_delete_node(self->nt, node) : 0; | |
|
2005 | return self->ntinitialized ? nt_delete_node(&self->nt, node) : 0; | |
|
2001 | 2006 | rev = PyInt_AsLong(value); |
|
2002 | 2007 | if (rev > INT_MAX || rev < 0) { |
|
2003 | 2008 | if (!PyErr_Occurred()) |
@@ -2007,7 +2012,7 b' static int index_assign_subscript(indexO' | |||
|
2007 | 2012 | |
|
2008 | 2013 | if (index_init_nt(self) == -1) |
|
2009 | 2014 | return -1; |
|
2010 | return nt_insert(self->nt, node, (int)rev); | |
|
2015 | return nt_insert(&self->nt, node, (int)rev); | |
|
2011 | 2016 | } |
|
2012 | 2017 | |
|
2013 | 2018 | /* |
@@ -2056,7 +2061,7 b' static int index_init(indexObject *self,' | |||
|
2056 | 2061 | self->headrevs = NULL; |
|
2057 | 2062 | self->filteredrevs = Py_None; |
|
2058 | 2063 | Py_INCREF(Py_None); |
|
2059 |
self->nt = |
|
|
2064 | self->ntinitialized = 0; | |
|
2060 | 2065 | self->offsets = NULL; |
|
2061 | 2066 | |
|
2062 | 2067 | if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj)) |
@@ -2118,10 +2123,10 b' static void _index_clearcaches(indexObje' | |||
|
2118 | 2123 | PyMem_Free((void *)self->offsets); |
|
2119 | 2124 | self->offsets = NULL; |
|
2120 | 2125 | } |
|
2121 |
if (self->nt |
|
|
2122 | nt_dealloc(self->nt); | |
|
2126 | if (self->ntinitialized) { | |
|
2127 | nt_dealloc(&self->nt); | |
|
2123 | 2128 | } |
|
2124 |
self->nt = |
|
|
2129 | self->ntinitialized = 0; | |
|
2125 | 2130 | Py_CLEAR(self->headrevs); |
|
2126 | 2131 | } |
|
2127 | 2132 | |
@@ -2143,7 +2148,6 b' static void index_dealloc(indexObject *s' | |||
|
2143 | 2148 | } |
|
2144 | 2149 | Py_XDECREF(self->data); |
|
2145 | 2150 | Py_XDECREF(self->added); |
|
2146 | Py_XDECREF(self->nt); | |
|
2147 | 2151 | PyObject_Del(self); |
|
2148 | 2152 | } |
|
2149 | 2153 |
General Comments 0
You need to be logged in to leave comments.
Login now