Show More
@@ -246,6 +246,7 b' typedef struct {' | |||
|
246 | 246 | Py_ssize_t raw_length; /* original number of elements */ |
|
247 | 247 | Py_ssize_t length; /* current number of elements */ |
|
248 | 248 | PyObject *added; /* populated on demand */ |
|
249 | PyObject *headrevs; /* cache, invalidated on changes */ | |
|
249 | 250 | nodetree *nt; /* base-16 trie */ |
|
250 | 251 | int ntlength; /* # nodes in use */ |
|
251 | 252 | int ntcapacity; /* # nodes allocated */ |
@@ -463,6 +464,7 b' static PyObject *index_insert(indexObjec' | |||
|
463 | 464 | if (self->nt) |
|
464 | 465 | nt_insert(self, node, (int)offset); |
|
465 | 466 | |
|
467 | Py_CLEAR(self->headrevs); | |
|
466 | 468 | Py_RETURN_NONE; |
|
467 | 469 | } |
|
468 | 470 | |
@@ -484,6 +486,7 b' static void _index_clearcaches(indexObje' | |||
|
484 | 486 | free(self->nt); |
|
485 | 487 | self->nt = NULL; |
|
486 | 488 | } |
|
489 | Py_CLEAR(self->headrevs); | |
|
487 | 490 | } |
|
488 | 491 | |
|
489 | 492 | static PyObject *index_clearcaches(indexObject *self) |
@@ -534,12 +537,37 b' bail:' | |||
|
534 | 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 | 562 | static PyObject *index_headrevs(indexObject *self) |
|
538 | 563 | { |
|
539 | 564 | Py_ssize_t i, len, addlen; |
|
540 | 565 | char *nothead = NULL; |
|
541 | 566 | PyObject *heads; |
|
542 | 567 | |
|
568 | if (self->headrevs) | |
|
569 | return list_copy(self->headrevs); | |
|
570 | ||
|
543 | 571 | len = index_length(self) - 1; |
|
544 | 572 | heads = PyList_New(0); |
|
545 | 573 | if (heads == NULL) |
@@ -601,8 +629,9 b' static PyObject *index_headrevs(indexObj' | |||
|
601 | 629 | } |
|
602 | 630 | |
|
603 | 631 | done: |
|
632 | self->headrevs = heads; | |
|
604 | 633 | free(nothead); |
|
605 | return heads; | |
|
634 | return list_copy(self->headrevs); | |
|
606 | 635 | bail: |
|
607 | 636 | Py_XDECREF(heads); |
|
608 | 637 | free(nothead); |
@@ -1065,6 +1094,7 b' static int index_slice_del(indexObject *' | |||
|
1065 | 1094 | ret = PyList_SetSlice(self->added, start - self->length + 1, |
|
1066 | 1095 | PyList_GET_SIZE(self->added), NULL); |
|
1067 | 1096 | done: |
|
1097 | Py_CLEAR(self->headrevs); | |
|
1068 | 1098 | return ret; |
|
1069 | 1099 | } |
|
1070 | 1100 | |
@@ -1155,6 +1185,7 b' static int index_init(indexObject *self,' | |||
|
1155 | 1185 | self->cache = NULL; |
|
1156 | 1186 | |
|
1157 | 1187 | self->added = NULL; |
|
1188 | self->headrevs = NULL; | |
|
1158 | 1189 | self->offsets = NULL; |
|
1159 | 1190 | self->nt = NULL; |
|
1160 | 1191 | self->ntlength = self->ntcapacity = 0; |
General Comments 0
You need to be logged in to leave comments.
Login now