equal
deleted
inserted
replaced
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; |