mercurial/cext/revlog.c
changeset 39218 b85b377e7fc2
parent 39075 b935adb4b041
child 39219 f85b25608252
equal deleted inserted replaced
39217:5961517fd2a8 39218:b85b377e7fc2
    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
    45 	indexObject *index;
    46 	indexObject *index;
    46 	nodetreenode *nodes;
    47 	nodetreenode *nodes;
    47 	unsigned length;     /* # nodes in use */
    48 	unsigned length;     /* # nodes in use */
    48 	unsigned capacity;   /* # nodes allocated */
    49 	unsigned capacity;   /* # nodes allocated */
    49 	int depth;           /* maximum depth of tree */
    50 	int depth;           /* maximum depth of tree */
  1062 	return nt_insert(self, node, -2);
  1063 	return nt_insert(self, node, -2);
  1063 }
  1064 }
  1064 
  1065 
  1065 static int nt_init(nodetree *self, indexObject *index, unsigned capacity)
  1066 static int nt_init(nodetree *self, indexObject *index, unsigned capacity)
  1066 {
  1067 {
       
  1068 	/* Initialize before argument-checking to avoid nt_dealloc() crash. */
       
  1069 	self->nodes = NULL;
       
  1070 
  1067 	self->index = index;
  1071 	self->index = index;
       
  1072 	Py_INCREF(index);
  1068 	/* The input capacity is in terms of revisions, while the field is in
  1073 	/* The input capacity is in terms of revisions, while the field is in
  1069 	 * terms of nodetree nodes. */
  1074 	 * terms of nodetree nodes. */
  1070 	self->capacity = (capacity < 4 ? 4 : capacity / 2);
  1075 	self->capacity = (capacity < 4 ? 4 : capacity / 2);
  1071 	self->depth = 0;
  1076 	self->depth = 0;
  1072 	self->splits = 0;
  1077 	self->splits = 0;
  1079 		PyErr_NoMemory();
  1084 		PyErr_NoMemory();
  1080 		return -1;
  1085 		return -1;
  1081 	}
  1086 	}
  1082 	self->length = 1;
  1087 	self->length = 1;
  1083 	return 0;
  1088 	return 0;
       
  1089 }
       
  1090 
       
  1091 static PyTypeObject indexType;
       
  1092 
       
  1093 static int nt_init_py(nodetree *self, PyObject *args)
       
  1094 {
       
  1095 	PyObject *index;
       
  1096 	unsigned capacity;
       
  1097 	if (!PyArg_ParseTuple(args, "O!I", &indexType, &index, &capacity))
       
  1098 		return -1;
       
  1099 	return nt_init(self, (indexObject*)index, capacity);
  1084 }
  1100 }
  1085 
  1101 
  1086 static int nt_partialmatch(nodetree *self, const char *node,
  1102 static int nt_partialmatch(nodetree *self, const char *node,
  1087 			   Py_ssize_t nodelen)
  1103 			   Py_ssize_t nodelen)
  1088 {
  1104 {
  1133 	 */
  1149 	 */
  1134 	PyErr_SetString(PyExc_Exception, "broken node tree");
  1150 	PyErr_SetString(PyExc_Exception, "broken node tree");
  1135 	return -3;
  1151 	return -3;
  1136 }
  1152 }
  1137 
  1153 
       
  1154 static void nt_dealloc(nodetree *self)
       
  1155 {
       
  1156 	Py_XDECREF(self->index);
       
  1157 	free(self->nodes);
       
  1158 	self->nodes = NULL;
       
  1159 	PyObject_Del(self);
       
  1160 }
       
  1161 
       
  1162 static PyTypeObject nodetreeType = {
       
  1163 	PyVarObject_HEAD_INIT(NULL, 0) /* header */
       
  1164 	"parsers.nodetree",        /* tp_name */
       
  1165 	sizeof(nodetree) ,         /* tp_basicsize */
       
  1166 	0,                         /* tp_itemsize */
       
  1167 	(destructor)nt_dealloc,    /* tp_dealloc */
       
  1168 	0,                         /* tp_print */
       
  1169 	0,                         /* tp_getattr */
       
  1170 	0,                         /* tp_setattr */
       
  1171 	0,                         /* tp_compare */
       
  1172 	0,                         /* tp_repr */
       
  1173 	0,                         /* tp_as_number */
       
  1174 	0,                         /* tp_as_sequence */
       
  1175 	0,                         /* tp_as_mapping */
       
  1176 	0,                         /* tp_hash */
       
  1177 	0,                         /* tp_call */
       
  1178 	0,                         /* tp_str */
       
  1179 	0,                         /* tp_getattro */
       
  1180 	0,                         /* tp_setattro */
       
  1181 	0,                         /* tp_as_buffer */
       
  1182 	Py_TPFLAGS_DEFAULT,        /* tp_flags */
       
  1183 	"nodetree",                /* tp_doc */
       
  1184 	0,                         /* tp_traverse */
       
  1185 	0,                         /* tp_clear */
       
  1186 	0,                         /* tp_richcompare */
       
  1187 	0,                         /* tp_weaklistoffset */
       
  1188 	0,                         /* tp_iter */
       
  1189 	0,                         /* tp_iternext */
       
  1190 	0,                         /* tp_methods */
       
  1191 	0,                         /* tp_members */
       
  1192 	0,                         /* tp_getset */
       
  1193 	0,                         /* tp_base */
       
  1194 	0,                         /* tp_dict */
       
  1195 	0,                         /* tp_descr_get */
       
  1196 	0,                         /* tp_descr_set */
       
  1197 	0,                         /* tp_dictoffset */
       
  1198 	(initproc)nt_init_py,      /* tp_init */
       
  1199 	0,                         /* tp_alloc */
       
  1200 };
       
  1201 
  1138 static int index_init_nt(indexObject *self)
  1202 static int index_init_nt(indexObject *self)
  1139 {
  1203 {
  1140 	if (self->nt == NULL) {
  1204 	if (self->nt == NULL) {
  1141 		self->nt = PyMem_Malloc(sizeof(nodetree));
  1205 		self->nt = PyObject_New(nodetree, &nodetreeType);
  1142 		if (self->nt == NULL) {
  1206 		if (self->nt == NULL) {
  1143 			PyErr_NoMemory();
       
  1144 			return -1;
  1207 			return -1;
  1145 		}
  1208 		}
  1146 		if (nt_init(self->nt, self, self->raw_length) == -1) {
  1209 		if (nt_init(self->nt, self, self->raw_length) == -1) {
  1147 			PyMem_Free(self->nt);
  1210 			nt_dealloc(self->nt);
  1148 			self->nt = NULL;
  1211 			self->nt = NULL;
  1149 			return -1;
  1212 			return -1;
  1150 		}
  1213 		}
  1151 		if (nt_insert(self->nt, nullid, -1) == -1) {
  1214 		if (nt_insert(self->nt, nullid, -1) == -1) {
  1152 			PyMem_Free(self->nt);
  1215 			nt_dealloc(self->nt);
  1153 			self->nt = NULL;
  1216 			self->nt = NULL;
  1154 			return -1;
  1217 			return -1;
  1155 		}
  1218 		}
  1156 		self->ntrev = (int)index_length(self);
  1219 		self->ntrev = (int)index_length(self);
  1157 		self->ntlookups = 1;
  1220 		self->ntlookups = 1;
  2007 	if (self->offsets) {
  2070 	if (self->offsets) {
  2008 		PyMem_Free((void *)self->offsets);
  2071 		PyMem_Free((void *)self->offsets);
  2009 		self->offsets = NULL;
  2072 		self->offsets = NULL;
  2010 	}
  2073 	}
  2011 	if (self->nt != NULL) {
  2074 	if (self->nt != NULL) {
  2012 		free(self->nt->nodes);
  2075 		nt_dealloc(self->nt);
  2013 		PyMem_Free(self->nt);
       
  2014 	}
  2076 	}
  2015 	self->nt = NULL;
  2077 	self->nt = NULL;
  2016 	Py_CLEAR(self->headrevs);
  2078 	Py_CLEAR(self->headrevs);
  2017 }
  2079 }
  2018 
  2080 
  2032 		PyBuffer_Release(&self->buf);
  2094 		PyBuffer_Release(&self->buf);
  2033 		memset(&self->buf, 0, sizeof(self->buf));
  2095 		memset(&self->buf, 0, sizeof(self->buf));
  2034 	}
  2096 	}
  2035 	Py_XDECREF(self->data);
  2097 	Py_XDECREF(self->data);
  2036 	Py_XDECREF(self->added);
  2098 	Py_XDECREF(self->added);
       
  2099 	Py_XDECREF(self->nt);
  2037 	PyObject_Del(self);
  2100 	PyObject_Del(self);
  2038 }
  2101 }
  2039 
  2102 
  2040 static PySequenceMethods index_sequence_methods = {
  2103 static PySequenceMethods index_sequence_methods = {
  2041 	(lenfunc)index_length,   /* sq_length */
  2104 	(lenfunc)index_length,   /* sq_length */
  2181 	if (PyType_Ready(&indexType) < 0)
  2244 	if (PyType_Ready(&indexType) < 0)
  2182 		return;
  2245 		return;
  2183 	Py_INCREF(&indexType);
  2246 	Py_INCREF(&indexType);
  2184 	PyModule_AddObject(mod, "index", (PyObject *)&indexType);
  2247 	PyModule_AddObject(mod, "index", (PyObject *)&indexType);
  2185 
  2248 
       
  2249 	nodetreeType.tp_new = PyType_GenericNew;
       
  2250 	if (PyType_Ready(&nodetreeType) < 0)
       
  2251 		return;
       
  2252 	Py_INCREF(&nodetreeType);
       
  2253 	PyModule_AddObject(mod, "nodetree", (PyObject *)&nodetreeType);
       
  2254 
  2186 	nullentry = Py_BuildValue(PY23("iiiiiiis#", "iiiiiiiy#"), 0, 0, 0,
  2255 	nullentry = Py_BuildValue(PY23("iiiiiiis#", "iiiiiiiy#"), 0, 0, 0,
  2187 				  -1, -1, -1, -1, nullid, 20);
  2256 				  -1, -1, -1, -1, nullid, 20);
  2188 	if (nullentry)
  2257 	if (nullentry)
  2189 		PyObject_GC_UnTrack(nullentry);
  2258 		PyObject_GC_UnTrack(nullentry);
  2190 }
  2259 }