mercurial/cext/revlog.c
changeset 39291 9f097214fbf3
parent 39228 66f046116105
child 39415 b69fbdd77c40
equal deleted inserted replaced
39290:286a666365ec 39291:9f097214fbf3
    40  * Positive value is index of the next node in the trie
    40  * Positive value is index of the next node in the trie
    41  * Negative value is a leaf: -(rev + 2)
    41  * Negative value is a leaf: -(rev + 2)
    42  * Zero is empty
    42  * Zero is empty
    43  */
    43  */
    44 typedef struct {
    44 typedef struct {
    45 	PyObject_HEAD
       
    46 	indexObject *index;
    45 	indexObject *index;
    47 	nodetreenode *nodes;
    46 	nodetreenode *nodes;
    48 	unsigned length;     /* # nodes in use */
    47 	unsigned length;     /* # nodes in use */
    49 	unsigned capacity;   /* # nodes allocated */
    48 	unsigned capacity;   /* # nodes allocated */
    50 	int depth;           /* maximum depth of tree */
    49 	int depth;           /* maximum depth of tree */
    51 	int splits;          /* # splits performed */
    50 	int splits;          /* # splits performed */
    52 } nodetree;
    51 } nodetree;
       
    52 
       
    53 typedef struct {
       
    54 	PyObject_HEAD
       
    55 	nodetree nt;
       
    56 } nodetreeObject;
    53 
    57 
    54 /*
    58 /*
    55  * This class has two behaviors.
    59  * This class has two behaviors.
    56  *
    60  *
    57  * When used in a list-like way (with integer keys), we decode an
    61  * When used in a list-like way (with integer keys), we decode an
    73 	Py_ssize_t raw_length; /* original number of elements */
    77 	Py_ssize_t raw_length; /* original number of elements */
    74 	Py_ssize_t length;     /* current number of elements */
    78 	Py_ssize_t length;     /* current number of elements */
    75 	PyObject *added;       /* populated on demand */
    79 	PyObject *added;       /* populated on demand */
    76 	PyObject *headrevs;    /* cache, invalidated on changes */
    80 	PyObject *headrevs;    /* cache, invalidated on changes */
    77 	PyObject *filteredrevs;/* filtered revs set */
    81 	PyObject *filteredrevs;/* filtered revs set */
    78 	nodetree *nt;          /* base-16 trie */
    82 	nodetree nt;           /* base-16 trie */
       
    83 	int ntinitialized;     /* 0 or 1 */
    79 	int ntrev;             /* last rev scanned */
    84 	int ntrev;             /* last rev scanned */
    80 	int ntlookups;         /* # lookups */
    85 	int ntlookups;         /* # lookups */
    81 	int ntmisses;          /* # lookups that miss the cache */
    86 	int ntmisses;          /* # lookups that miss the cache */
    82 	int inlined;
    87 	int inlined;
    83 };
    88 };
   331 	}
   336 	}
   332 
   337 
   333 	if (PyList_Append(self->added, obj) == -1)
   338 	if (PyList_Append(self->added, obj) == -1)
   334 		return NULL;
   339 		return NULL;
   335 
   340 
   336 	if (self->nt)
   341 	if (self->ntinitialized)
   337 		nt_insert(self->nt, node, (int)len);
   342 		nt_insert(&self->nt, node, (int)len);
   338 
   343 
   339 	Py_CLEAR(self->headrevs);
   344 	Py_CLEAR(self->headrevs);
   340 	Py_RETURN_NONE;
   345 	Py_RETURN_NONE;
   341 }
   346 }
   342 
   347 
   372 		istat(raw_length, "revs on disk");
   377 		istat(raw_length, "revs on disk");
   373 	istat(length, "revs in memory");
   378 	istat(length, "revs in memory");
   374 	istat(ntlookups, "node trie lookups");
   379 	istat(ntlookups, "node trie lookups");
   375 	istat(ntmisses, "node trie misses");
   380 	istat(ntmisses, "node trie misses");
   376 	istat(ntrev, "node trie last rev scanned");
   381 	istat(ntrev, "node trie last rev scanned");
   377 	if (self->nt) {
   382 	if (self->ntinitialized) {
   378 		istat(nt->capacity, "node trie capacity");
   383 		istat(nt.capacity, "node trie capacity");
   379 		istat(nt->depth, "node trie depth");
   384 		istat(nt.depth, "node trie depth");
   380 		istat(nt->length, "node trie count");
   385 		istat(nt.length, "node trie count");
   381 		istat(nt->splits, "node trie splits");
   386 		istat(nt.splits, "node trie splits");
   382 	}
   387 	}
   383 
   388 
   384 #undef istat
   389 #undef istat
   385 
   390 
   386 	return obj;
   391 	return obj;
  1085 	}
  1090 	}
  1086 
  1091 
  1087 	return -1;
  1092 	return -1;
  1088 }
  1093 }
  1089 
  1094 
  1090 static PyObject *nt_insert_py(nodetree *self, PyObject *args)
  1095 static PyObject *ntobj_insert(nodetreeObject *self, PyObject *args)
  1091 {
  1096 {
  1092 	Py_ssize_t rev;
  1097 	Py_ssize_t rev;
  1093 	const char *node;
  1098 	const char *node;
  1094 	Py_ssize_t length;
  1099 	Py_ssize_t length;
  1095 	if (!PyArg_ParseTuple(args, "n", &rev))
  1100 	if (!PyArg_ParseTuple(args, "n", &rev))
  1096 		return NULL;
  1101 		return NULL;
  1097 	length = index_length(self->index);
  1102 	length = index_length(self->nt.index);
  1098 	if (rev < 0 || rev >= length) {
  1103 	if (rev < 0 || rev >= length) {
  1099 		PyErr_SetString(PyExc_ValueError, "revlog index out of range");
  1104 		PyErr_SetString(PyExc_ValueError, "revlog index out of range");
  1100 		return NULL;
  1105 		return NULL;
  1101 	}
  1106 	}
  1102 	node = index_node_existing(self->index, rev);
  1107 	node = index_node_existing(self->nt.index, rev);
  1103 	if (nt_insert(self, node, (int)rev) == -1)
  1108 	if (nt_insert(&self->nt, node, (int)rev) == -1)
  1104 		return NULL;
  1109 		return NULL;
  1105 	Py_RETURN_NONE;
  1110 	Py_RETURN_NONE;
  1106 }
  1111 }
  1107 
  1112 
  1108 static int nt_delete_node(nodetree *self, const char *node)
  1113 static int nt_delete_node(nodetree *self, const char *node)
  1115 {
  1120 {
  1116 	/* Initialize before overflow-checking to avoid nt_dealloc() crash. */
  1121 	/* Initialize before overflow-checking to avoid nt_dealloc() crash. */
  1117 	self->nodes = NULL;
  1122 	self->nodes = NULL;
  1118 
  1123 
  1119 	self->index = index;
  1124 	self->index = index;
  1120 	Py_INCREF(index);
       
  1121 	/* The input capacity is in terms of revisions, while the field is in
  1125 	/* The input capacity is in terms of revisions, while the field is in
  1122 	 * terms of nodetree nodes. */
  1126 	 * terms of nodetree nodes. */
  1123 	self->capacity = (capacity < 4 ? 4 : capacity / 2);
  1127 	self->capacity = (capacity < 4 ? 4 : capacity / 2);
  1124 	self->depth = 0;
  1128 	self->depth = 0;
  1125 	self->splits = 0;
  1129 	self->splits = 0;
  1136 	return 0;
  1140 	return 0;
  1137 }
  1141 }
  1138 
  1142 
  1139 static PyTypeObject indexType;
  1143 static PyTypeObject indexType;
  1140 
  1144 
  1141 static int nt_init_py(nodetree *self, PyObject *args)
  1145 static int ntobj_init(nodetreeObject *self, PyObject *args)
  1142 {
  1146 {
  1143 	PyObject *index;
  1147 	PyObject *index;
  1144 	unsigned capacity;
  1148 	unsigned capacity;
  1145 	if (!PyArg_ParseTuple(args, "O!I", &indexType, &index, &capacity))
  1149 	if (!PyArg_ParseTuple(args, "O!I", &indexType, &index, &capacity))
  1146 		return -1;
  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 static int nt_partialmatch(nodetree *self, const char *node,
  1155 static int nt_partialmatch(nodetree *self, const char *node,
  1151 			   Py_ssize_t nodelen)
  1156 			   Py_ssize_t nodelen)
  1152 {
  1157 {
  1197 	 */
  1202 	 */
  1198 	PyErr_SetString(PyExc_Exception, "broken node tree");
  1203 	PyErr_SetString(PyExc_Exception, "broken node tree");
  1199 	return -3;
  1204 	return -3;
  1200 }
  1205 }
  1201 
  1206 
  1202 static PyObject *nt_shortest_py(nodetree *self, PyObject *args)
  1207 static PyObject *ntobj_shortest(nodetreeObject *self, PyObject *args)
  1203 {
  1208 {
  1204 	PyObject *val;
  1209 	PyObject *val;
  1205 	char *node;
  1210 	char *node;
  1206 	int length;
  1211 	int length;
  1207 
  1212 
  1208 	if (!PyArg_ParseTuple(args, "O", &val))
  1213 	if (!PyArg_ParseTuple(args, "O", &val))
  1209 		return NULL;
  1214 		return NULL;
  1210 	if (node_check(val, &node) == -1)
  1215 	if (node_check(val, &node) == -1)
  1211 		return NULL;
  1216 		return NULL;
  1212 
  1217 
  1213 	length = nt_shortest(self, node);
  1218 	length = nt_shortest(&self->nt, node);
  1214 	if (length == -3)
  1219 	if (length == -3)
  1215 		return NULL;
  1220 		return NULL;
  1216 	if (length == -2) {
  1221 	if (length == -2) {
  1217 		raise_revlog_error();
  1222 		raise_revlog_error();
  1218 		return NULL;
  1223 		return NULL;
  1220 	return PyInt_FromLong(length);
  1225 	return PyInt_FromLong(length);
  1221 }
  1226 }
  1222 
  1227 
  1223 static void nt_dealloc(nodetree *self)
  1228 static void nt_dealloc(nodetree *self)
  1224 {
  1229 {
  1225 	Py_XDECREF(self->index);
       
  1226 	free(self->nodes);
  1230 	free(self->nodes);
  1227 	self->nodes = NULL;
  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 	PyObject_Del(self);
  1238 	PyObject_Del(self);
  1229 }
  1239 }
  1230 
  1240 
  1231 static PyMethodDef nt_methods[] = {
  1241 static PyMethodDef ntobj_methods[] = {
  1232 	{"insert", (PyCFunction)nt_insert_py, METH_VARARGS,
  1242 	{"insert", (PyCFunction)ntobj_insert, METH_VARARGS,
  1233 	 "insert an index entry"},
  1243 	 "insert an index entry"},
  1234 	{"shortest", (PyCFunction)nt_shortest_py, METH_VARARGS,
  1244 	{"shortest", (PyCFunction)ntobj_shortest, METH_VARARGS,
  1235 	 "find length of shortest hex nodeid of a binary ID"},
  1245 	 "find length of shortest hex nodeid of a binary ID"},
  1236 	{NULL} /* Sentinel */
  1246 	{NULL} /* Sentinel */
  1237 };
  1247 };
  1238 
  1248 
  1239 static PyTypeObject nodetreeType = {
  1249 static PyTypeObject nodetreeType = {
  1240 	PyVarObject_HEAD_INIT(NULL, 0) /* header */
  1250 	PyVarObject_HEAD_INIT(NULL, 0) /* header */
  1241 	"parsers.nodetree",        /* tp_name */
  1251 	"parsers.nodetree",        /* tp_name */
  1242 	sizeof(nodetree) ,         /* tp_basicsize */
  1252 	sizeof(nodetree) ,         /* tp_basicsize */
  1243 	0,                         /* tp_itemsize */
  1253 	0,                         /* tp_itemsize */
  1244 	(destructor)nt_dealloc,    /* tp_dealloc */
  1254 	(destructor)ntobj_dealloc, /* tp_dealloc */
  1245 	0,                         /* tp_print */
  1255 	0,                         /* tp_print */
  1246 	0,                         /* tp_getattr */
  1256 	0,                         /* tp_getattr */
  1247 	0,                         /* tp_setattr */
  1257 	0,                         /* tp_setattr */
  1248 	0,                         /* tp_compare */
  1258 	0,                         /* tp_compare */
  1249 	0,                         /* tp_repr */
  1259 	0,                         /* tp_repr */
  1262 	0,                         /* tp_clear */
  1272 	0,                         /* tp_clear */
  1263 	0,                         /* tp_richcompare */
  1273 	0,                         /* tp_richcompare */
  1264 	0,                         /* tp_weaklistoffset */
  1274 	0,                         /* tp_weaklistoffset */
  1265 	0,                         /* tp_iter */
  1275 	0,                         /* tp_iter */
  1266 	0,                         /* tp_iternext */
  1276 	0,                         /* tp_iternext */
  1267 	nt_methods,                /* tp_methods */
  1277 	ntobj_methods,             /* tp_methods */
  1268 	0,                         /* tp_members */
  1278 	0,                         /* tp_members */
  1269 	0,                         /* tp_getset */
  1279 	0,                         /* tp_getset */
  1270 	0,                         /* tp_base */
  1280 	0,                         /* tp_base */
  1271 	0,                         /* tp_dict */
  1281 	0,                         /* tp_dict */
  1272 	0,                         /* tp_descr_get */
  1282 	0,                         /* tp_descr_get */
  1273 	0,                         /* tp_descr_set */
  1283 	0,                         /* tp_descr_set */
  1274 	0,                         /* tp_dictoffset */
  1284 	0,                         /* tp_dictoffset */
  1275 	(initproc)nt_init_py,      /* tp_init */
  1285 	(initproc)ntobj_init,      /* tp_init */
  1276 	0,                         /* tp_alloc */
  1286 	0,                         /* tp_alloc */
  1277 };
  1287 };
  1278 
  1288 
  1279 static int index_init_nt(indexObject *self)
  1289 static int index_init_nt(indexObject *self)
  1280 {
  1290 {
  1281 	if (self->nt == NULL) {
  1291 	if (!self->ntinitialized) {
  1282 		self->nt = PyObject_New(nodetree, &nodetreeType);
  1292 		if (nt_init(&self->nt, self, (int)self->raw_length) == -1) {
  1283 		if (self->nt == NULL) {
  1293 			nt_dealloc(&self->nt);
  1284 			return -1;
  1294 			return -1;
  1285 		}
  1295 		}
  1286 		if (nt_init(self->nt, self, (int)self->raw_length) == -1) {
  1296 		if (nt_insert(&self->nt, nullid, -1) == -1) {
  1287 			nt_dealloc(self->nt);
  1297 			nt_dealloc(&self->nt);
  1288 			self->nt = NULL;
       
  1289 			return -1;
  1298 			return -1;
  1290 		}
  1299 		}
  1291 		if (nt_insert(self->nt, nullid, -1) == -1) {
  1300 		self->ntinitialized = 1;
  1292 			nt_dealloc(self->nt);
       
  1293 			self->nt = NULL;
       
  1294 			return -1;
       
  1295 		}
       
  1296 		self->ntrev = (int)index_length(self);
  1301 		self->ntrev = (int)index_length(self);
  1297 		self->ntlookups = 1;
  1302 		self->ntlookups = 1;
  1298 		self->ntmisses = 0;
  1303 		self->ntmisses = 0;
  1299 	}
  1304 	}
  1300 	return 0;
  1305 	return 0;
  1314 
  1319 
  1315 	if (index_init_nt(self) == -1)
  1320 	if (index_init_nt(self) == -1)
  1316 		return -3;
  1321 		return -3;
  1317 
  1322 
  1318 	self->ntlookups++;
  1323 	self->ntlookups++;
  1319 	rev = nt_find(self->nt, node, nodelen, 0);
  1324 	rev = nt_find(&self->nt, node, nodelen, 0);
  1320 	if (rev >= -1)
  1325 	if (rev >= -1)
  1321 		return rev;
  1326 		return rev;
  1322 
  1327 
  1323 	/*
  1328 	/*
  1324 	 * For the first handful of lookups, we scan the entire index,
  1329 	 * For the first handful of lookups, we scan the entire index,
  1333 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
  1338 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
  1334 			const char *n = index_node_existing(self, rev);
  1339 			const char *n = index_node_existing(self, rev);
  1335 			if (n == NULL)
  1340 			if (n == NULL)
  1336 				return -3;
  1341 				return -3;
  1337 			if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
  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 					return -3;
  1344 					return -3;
  1340 				break;
  1345 				break;
  1341 			}
  1346 			}
  1342 		}
  1347 		}
  1343 	} else {
  1348 	} else {
  1344 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
  1349 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
  1345 			const char *n = index_node_existing(self, rev);
  1350 			const char *n = index_node_existing(self, rev);
  1346 			if (n == NULL)
  1351 			if (n == NULL)
  1347 				return -3;
  1352 				return -3;
  1348 			if (nt_insert(self->nt, n, rev) == -1) {
  1353 			if (nt_insert(&self->nt, n, rev) == -1) {
  1349 				self->ntrev = rev + 1;
  1354 				self->ntrev = rev + 1;
  1350 				return -3;
  1355 				return -3;
  1351 			}
  1356 			}
  1352 			if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
  1357 			if (memcmp(node, n, nodelen > 20 ? 20 : nodelen) == 0) {
  1353 				break;
  1358 				break;
  1387 	if (self->ntrev > 0) {
  1392 	if (self->ntrev > 0) {
  1388 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
  1393 		for (rev = self->ntrev - 1; rev >= 0; rev--) {
  1389 			const char *n = index_node_existing(self, rev);
  1394 			const char *n = index_node_existing(self, rev);
  1390 			if (n == NULL)
  1395 			if (n == NULL)
  1391 				return -1;
  1396 				return -1;
  1392 			if (nt_insert(self->nt, n, rev) == -1)
  1397 			if (nt_insert(&self->nt, n, rev) == -1)
  1393 				return -1;
  1398 				return -1;
  1394 		}
  1399 		}
  1395 		self->ntrev = -1;
  1400 		self->ntrev = -1;
  1396 	}
  1401 	}
  1397 	return 0;
  1402 	return 0;
  1427 
  1432 
  1428 	if (index_init_nt(self) == -1)
  1433 	if (index_init_nt(self) == -1)
  1429 		return NULL;
  1434 		return NULL;
  1430 	if (index_populate_nt(self) == -1)
  1435 	if (index_populate_nt(self) == -1)
  1431 		return NULL;
  1436 		return NULL;
  1432 	rev = nt_partialmatch(self->nt, node, nodelen);
  1437 	rev = nt_partialmatch(&self->nt, node, nodelen);
  1433 
  1438 
  1434 	switch (rev) {
  1439 	switch (rev) {
  1435 	case -4:
  1440 	case -4:
  1436 		raise_revlog_error();
  1441 		raise_revlog_error();
  1437 		return NULL;
  1442 		return NULL;
  1462 	self->ntlookups++;
  1467 	self->ntlookups++;
  1463 	if (index_init_nt(self) == -1)
  1468 	if (index_init_nt(self) == -1)
  1464 		return NULL;
  1469 		return NULL;
  1465 	if (index_populate_nt(self) == -1)
  1470 	if (index_populate_nt(self) == -1)
  1466 		return NULL;
  1471 		return NULL;
  1467 	length = nt_shortest(self->nt, node);
  1472 	length = nt_shortest(&self->nt, node);
  1468 	if (length == -3)
  1473 	if (length == -3)
  1469 		return NULL;
  1474 		return NULL;
  1470 	if (length == -2) {
  1475 	if (length == -2) {
  1471 		raise_revlog_error();
  1476 		raise_revlog_error();
  1472 		return NULL;
  1477 		return NULL;
  1884 
  1889 
  1885 	for (i = start; i < len; i++) {
  1890 	for (i = start; i < len; i++) {
  1886 		PyObject *tuple = PyList_GET_ITEM(self->added, i);
  1891 		PyObject *tuple = PyList_GET_ITEM(self->added, i);
  1887 		PyObject *node = PyTuple_GET_ITEM(tuple, 7);
  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 	if (start == 0)
  1897 	if (start == 0)
  1893 		Py_CLEAR(self->added);
  1898 		Py_CLEAR(self->added);
  1894 }
  1899 }
  1935 				"revlog index deletion indices are invalid");
  1940 				"revlog index deletion indices are invalid");
  1936 		return -1;
  1941 		return -1;
  1937 	}
  1942 	}
  1938 
  1943 
  1939 	if (start < self->length) {
  1944 	if (start < self->length) {
  1940 		if (self->nt) {
  1945 		if (self->ntinitialized) {
  1941 			Py_ssize_t i;
  1946 			Py_ssize_t i;
  1942 
  1947 
  1943 			for (i = start + 1; i < self->length; i++) {
  1948 			for (i = start + 1; i < self->length; i++) {
  1944 				const char *node = index_node_existing(self, i);
  1949 				const char *node = index_node_existing(self, i);
  1945 				if (node == NULL)
  1950 				if (node == NULL)
  1946 					return -1;
  1951 					return -1;
  1947 
  1952 
  1948 				nt_delete_node(self->nt, node);
  1953 				nt_delete_node(&self->nt, node);
  1949 			}
  1954 			}
  1950 			if (self->added)
  1955 			if (self->added)
  1951 				index_invalidate_added(self, 0);
  1956 				index_invalidate_added(self, 0);
  1952 			if (self->ntrev > start)
  1957 			if (self->ntrev > start)
  1953 				self->ntrev = (int)start;
  1958 				self->ntrev = (int)start;
  1962 			self->raw_length = start;
  1967 			self->raw_length = start;
  1963 		}
  1968 		}
  1964 		goto done;
  1969 		goto done;
  1965 	}
  1970 	}
  1966 
  1971 
  1967 	if (self->nt) {
  1972 	if (self->ntinitialized) {
  1968 		index_invalidate_added(self, start - self->length);
  1973 		index_invalidate_added(self, start - self->length);
  1969 		if (self->ntrev > start)
  1974 		if (self->ntrev > start)
  1970 			self->ntrev = (int)start;
  1975 			self->ntrev = (int)start;
  1971 	}
  1976 	}
  1972 	if (self->added)
  1977 	if (self->added)
  1995 
  2000 
  1996 	if (node_check(item, &node) == -1)
  2001 	if (node_check(item, &node) == -1)
  1997 		return -1;
  2002 		return -1;
  1998 
  2003 
  1999 	if (value == NULL)
  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 	rev = PyInt_AsLong(value);
  2006 	rev = PyInt_AsLong(value);
  2002 	if (rev > INT_MAX || rev < 0) {
  2007 	if (rev > INT_MAX || rev < 0) {
  2003 		if (!PyErr_Occurred())
  2008 		if (!PyErr_Occurred())
  2004 			PyErr_SetString(PyExc_ValueError, "rev out of range");
  2009 			PyErr_SetString(PyExc_ValueError, "rev out of range");
  2005 		return -1;
  2010 		return -1;
  2006 	}
  2011 	}
  2007 
  2012 
  2008 	if (index_init_nt(self) == -1)
  2013 	if (index_init_nt(self) == -1)
  2009 		return -1;
  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 /*
  2014  * Find all RevlogNG entries in an index that has inline data. Update
  2019  * Find all RevlogNG entries in an index that has inline data. Update
  2015  * the optional "offsets" table with those entries.
  2020  * the optional "offsets" table with those entries.
  2054 	self->data = NULL;
  2059 	self->data = NULL;
  2055 	memset(&self->buf, 0, sizeof(self->buf));
  2060 	memset(&self->buf, 0, sizeof(self->buf));
  2056 	self->headrevs = NULL;
  2061 	self->headrevs = NULL;
  2057 	self->filteredrevs = Py_None;
  2062 	self->filteredrevs = Py_None;
  2058 	Py_INCREF(Py_None);
  2063 	Py_INCREF(Py_None);
  2059 	self->nt = NULL;
  2064 	self->ntinitialized = 0;
  2060 	self->offsets = NULL;
  2065 	self->offsets = NULL;
  2061 
  2066 
  2062 	if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj))
  2067 	if (!PyArg_ParseTuple(args, "OO", &data_obj, &inlined_obj))
  2063 		return -1;
  2068 		return -1;
  2064 	if (!PyObject_CheckBuffer(data_obj)) {
  2069 	if (!PyObject_CheckBuffer(data_obj)) {
  2116 	}
  2121 	}
  2117 	if (self->offsets) {
  2122 	if (self->offsets) {
  2118 		PyMem_Free((void *)self->offsets);
  2123 		PyMem_Free((void *)self->offsets);
  2119 		self->offsets = NULL;
  2124 		self->offsets = NULL;
  2120 	}
  2125 	}
  2121 	if (self->nt != NULL) {
  2126 	if (self->ntinitialized) {
  2122 		nt_dealloc(self->nt);
  2127 		nt_dealloc(&self->nt);
  2123 	}
  2128 	}
  2124 	self->nt = NULL;
  2129 	self->ntinitialized = 0;
  2125 	Py_CLEAR(self->headrevs);
  2130 	Py_CLEAR(self->headrevs);
  2126 }
  2131 }
  2127 
  2132 
  2128 static PyObject *index_clearcaches(indexObject *self)
  2133 static PyObject *index_clearcaches(indexObject *self)
  2129 {
  2134 {
  2141 		PyBuffer_Release(&self->buf);
  2146 		PyBuffer_Release(&self->buf);
  2142 		memset(&self->buf, 0, sizeof(self->buf));
  2147 		memset(&self->buf, 0, sizeof(self->buf));
  2143 	}
  2148 	}
  2144 	Py_XDECREF(self->data);
  2149 	Py_XDECREF(self->data);
  2145 	Py_XDECREF(self->added);
  2150 	Py_XDECREF(self->added);
  2146 	Py_XDECREF(self->nt);
       
  2147 	PyObject_Del(self);
  2151 	PyObject_Del(self);
  2148 }
  2152 }
  2149 
  2153 
  2150 static PySequenceMethods index_sequence_methods = {
  2154 static PySequenceMethods index_sequence_methods = {
  2151 	(lenfunc)index_length,   /* sq_length */
  2155 	(lenfunc)index_length,   /* sq_length */