mercurial/parsers.c
changeset 16787 bda96ce993f9
parent 16786 2631cd5dd244
child 16863 bbedef66c6f3
equal deleted inserted replaced
16786:2631cd5dd244 16787:bda96ce993f9
   244 	PyObject **cache;      /* cached tuples */
   244 	PyObject **cache;      /* cached tuples */
   245 	const char **offsets;  /* populated on demand */
   245 	const char **offsets;  /* populated on demand */
   246 	Py_ssize_t raw_length; /* original number of elements */
   246 	Py_ssize_t raw_length; /* original number of elements */
   247 	Py_ssize_t length;     /* current number of elements */
   247 	Py_ssize_t length;     /* current number of elements */
   248 	PyObject *added;       /* populated on demand */
   248 	PyObject *added;       /* populated on demand */
       
   249 	PyObject *headrevs;    /* cache, invalidated on changes */
   249 	nodetree *nt;          /* base-16 trie */
   250 	nodetree *nt;          /* base-16 trie */
   250 	int ntlength;          /* # nodes in use */
   251 	int ntlength;          /* # nodes in use */
   251 	int ntcapacity;        /* # nodes allocated */
   252 	int ntcapacity;        /* # nodes allocated */
   252 	int ntdepth;           /* maximum depth of tree */
   253 	int ntdepth;           /* maximum depth of tree */
   253 	int ntsplits;          /* # splits performed */
   254 	int ntsplits;          /* # splits performed */
   461 		return NULL;
   462 		return NULL;
   462 
   463 
   463 	if (self->nt)
   464 	if (self->nt)
   464 		nt_insert(self, node, (int)offset);
   465 		nt_insert(self, node, (int)offset);
   465 
   466 
       
   467 	Py_CLEAR(self->headrevs);
   466 	Py_RETURN_NONE;
   468 	Py_RETURN_NONE;
   467 }
   469 }
   468 
   470 
   469 static void _index_clearcaches(indexObject *self)
   471 static void _index_clearcaches(indexObject *self)
   470 {
   472 {
   482 	}
   484 	}
   483 	if (self->nt) {
   485 	if (self->nt) {
   484 		free(self->nt);
   486 		free(self->nt);
   485 		self->nt = NULL;
   487 		self->nt = NULL;
   486 	}
   488 	}
       
   489 	Py_CLEAR(self->headrevs);
   487 }
   490 }
   488 
   491 
   489 static PyObject *index_clearcaches(indexObject *self)
   492 static PyObject *index_clearcaches(indexObject *self)
   490 {
   493 {
   491 	_index_clearcaches(self);
   494 	_index_clearcaches(self);
   532 bail:
   535 bail:
   533 	Py_XDECREF(obj);
   536 	Py_XDECREF(obj);
   534 	return NULL;
   537 	return NULL;
   535 }
   538 }
   536 
   539 
       
   540 /*
       
   541  * When we cache a list, we want to be sure the caller can't mutate
       
   542  * the cached copy.
       
   543  */
       
   544 static PyObject *list_copy(PyObject *list)
       
   545 {
       
   546 	Py_ssize_t len = PyList_GET_SIZE(list);
       
   547 	PyObject *newlist = PyList_New(len);
       
   548 	Py_ssize_t i;
       
   549 
       
   550 	if (newlist == NULL)
       
   551 		return NULL;
       
   552 
       
   553 	for (i = 0; i < len; i++) {
       
   554 		PyObject *obj = PyList_GET_ITEM(list, i);
       
   555 		Py_INCREF(obj);
       
   556 		PyList_SET_ITEM(newlist, i, obj);
       
   557 	}
       
   558 
       
   559 	return newlist;
       
   560 }
       
   561 
   537 static PyObject *index_headrevs(indexObject *self)
   562 static PyObject *index_headrevs(indexObject *self)
   538 {
   563 {
   539 	Py_ssize_t i, len, addlen;
   564 	Py_ssize_t i, len, addlen;
   540 	char *nothead = NULL;
   565 	char *nothead = NULL;
   541 	PyObject *heads;
   566 	PyObject *heads;
       
   567 
       
   568 	if (self->headrevs)
       
   569 		return list_copy(self->headrevs);
   542 
   570 
   543 	len = index_length(self) - 1;
   571 	len = index_length(self) - 1;
   544 	heads = PyList_New(0);
   572 	heads = PyList_New(0);
   545 	if (heads == NULL)
   573 	if (heads == NULL)
   546 		goto bail;
   574 		goto bail;
   599 			goto bail;
   627 			goto bail;
   600 		}
   628 		}
   601 	}
   629 	}
   602 
   630 
   603 done:
   631 done:
       
   632 	self->headrevs = heads;
   604 	free(nothead);
   633 	free(nothead);
   605 	return heads;
   634 	return list_copy(self->headrevs);
   606 bail:
   635 bail:
   607 	Py_XDECREF(heads);
   636 	Py_XDECREF(heads);
   608 	free(nothead);
   637 	free(nothead);
   609 	return NULL;
   638 	return NULL;
   610 }
   639 }
  1063 	}
  1092 	}
  1064 	if (self->added)
  1093 	if (self->added)
  1065 		ret = PyList_SetSlice(self->added, start - self->length + 1,
  1094 		ret = PyList_SetSlice(self->added, start - self->length + 1,
  1066 				      PyList_GET_SIZE(self->added), NULL);
  1095 				      PyList_GET_SIZE(self->added), NULL);
  1067 done:
  1096 done:
       
  1097 	Py_CLEAR(self->headrevs);
  1068 	return ret;
  1098 	return ret;
  1069 }
  1099 }
  1070 
  1100 
  1071 /*
  1101 /*
  1072  * Supported ops:
  1102  * Supported ops:
  1153 	self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
  1183 	self->inlined = inlined_obj && PyObject_IsTrue(inlined_obj);
  1154 	self->data = data_obj;
  1184 	self->data = data_obj;
  1155 	self->cache = NULL;
  1185 	self->cache = NULL;
  1156 
  1186 
  1157 	self->added = NULL;
  1187 	self->added = NULL;
       
  1188 	self->headrevs = NULL;
  1158 	self->offsets = NULL;
  1189 	self->offsets = NULL;
  1159 	self->nt = NULL;
  1190 	self->nt = NULL;
  1160 	self->ntlength = self->ntcapacity = 0;
  1191 	self->ntlength = self->ntcapacity = 0;
  1161 	self->ntdepth = self->ntsplits = 0;
  1192 	self->ntdepth = self->ntsplits = 0;
  1162 	self->ntlookups = self->ntmisses = 0;
  1193 	self->ntlookups = self->ntmisses = 0;