Show More
@@ -28,6 +28,10 b'' | |||||
28 | #define PyInt_AsLong PyLong_AsLong |
|
28 | #define PyInt_AsLong PyLong_AsLong | |
29 | #endif |
|
29 | #endif | |
30 |
|
30 | |||
|
31 | typedef struct { | |||
|
32 | int children[16]; | |||
|
33 | } nodetreenode; | |||
|
34 | ||||
31 | /* |
|
35 | /* | |
32 | * A base-16 trie for fast node->rev mapping. |
|
36 | * A base-16 trie for fast node->rev mapping. | |
33 | * |
|
37 | * | |
@@ -36,7 +40,7 b'' | |||||
36 | * Zero is empty |
|
40 | * Zero is empty | |
37 | */ |
|
41 | */ | |
38 | typedef struct { |
|
42 | typedef struct { | |
39 | int children[16]; |
|
43 | nodetreenode *nodes; | |
40 | } nodetree; |
|
44 | } nodetree; | |
41 |
|
45 | |||
42 | /* |
|
46 | /* | |
@@ -317,7 +321,10 b' static void _index_clearcaches(indexObje' | |||||
317 | PyMem_Free(self->offsets); |
|
321 | PyMem_Free(self->offsets); | |
318 | self->offsets = NULL; |
|
322 | self->offsets = NULL; | |
319 | } |
|
323 | } | |
|
324 | if (self->nt != NULL) { | |||
|
325 | free(self->nt->nodes); | |||
320 | free(self->nt); |
|
326 | free(self->nt); | |
|
327 | } | |||
321 | self->nt = NULL; |
|
328 | self->nt = NULL; | |
322 | Py_CLEAR(self->headrevs); |
|
329 | Py_CLEAR(self->headrevs); | |
323 | } |
|
330 | } | |
@@ -984,7 +991,7 b' static int nt_find(indexObject *self, co' | |||||
984 |
|
991 | |||
985 | for (level = off = 0; level < maxlevel; level++) { |
|
992 | for (level = off = 0; level < maxlevel; level++) { | |
986 | int k = getnybble(node, level); |
|
993 | int k = getnybble(node, level); | |
987 | nodetree *n = &self->nt[off]; |
|
994 | nodetreenode *n = &self->nt->nodes[off]; | |
988 | int v = n->children[k]; |
|
995 | int v = n->children[k]; | |
989 |
|
996 | |||
990 | if (v < 0) { |
|
997 | if (v < 0) { | |
@@ -1011,20 +1018,20 b' static int nt_find(indexObject *self, co' | |||||
1011 | static int nt_new(indexObject *self) |
|
1018 | static int nt_new(indexObject *self) | |
1012 | { |
|
1019 | { | |
1013 | if (self->ntlength == self->ntcapacity) { |
|
1020 | if (self->ntlength == self->ntcapacity) { | |
1014 | if (self->ntcapacity >= INT_MAX / (sizeof(nodetree) * 2)) { |
|
1021 | if (self->ntcapacity >= INT_MAX / (sizeof(nodetreenode) * 2)) { | |
1015 | PyErr_SetString(PyExc_MemoryError, |
|
1022 | PyErr_SetString(PyExc_MemoryError, | |
1016 | "overflow in nt_new"); |
|
1023 | "overflow in nt_new"); | |
1017 | return -1; |
|
1024 | return -1; | |
1018 | } |
|
1025 | } | |
1019 | self->ntcapacity *= 2; |
|
1026 | self->ntcapacity *= 2; | |
1020 | self->nt = realloc(self->nt, |
|
1027 | self->nt->nodes = realloc(self->nt->nodes, | |
1021 |
|
|
1028 | self->ntcapacity * sizeof(nodetreenode)); | |
1022 | if (self->nt == NULL) { |
|
1029 | if (self->nt->nodes == NULL) { | |
1023 | PyErr_SetString(PyExc_MemoryError, "out of memory"); |
|
1030 | PyErr_SetString(PyExc_MemoryError, "out of memory"); | |
1024 | return -1; |
|
1031 | return -1; | |
1025 | } |
|
1032 | } | |
1026 | memset(&self->nt[self->ntlength], 0, |
|
1033 | memset(&self->nt->nodes[self->ntlength], 0, | |
1027 | sizeof(nodetree) * (self->ntcapacity - self->ntlength)); |
|
1034 | sizeof(nodetreenode) * (self->ntcapacity - self->ntlength)); | |
1028 | } |
|
1035 | } | |
1029 | return self->ntlength++; |
|
1036 | return self->ntlength++; | |
1030 | } |
|
1037 | } | |
@@ -1036,10 +1043,10 b' static int nt_insert(indexObject *self, ' | |||||
1036 |
|
1043 | |||
1037 | while (level < 40) { |
|
1044 | while (level < 40) { | |
1038 | int k = nt_level(node, level); |
|
1045 | int k = nt_level(node, level); | |
1039 | nodetree *n; |
|
1046 | nodetreenode *n; | |
1040 | int v; |
|
1047 | int v; | |
1041 |
|
1048 | |||
1042 | n = &self->nt[off]; |
|
1049 | n = &self->nt->nodes[off]; | |
1043 | v = n->children[k]; |
|
1050 | v = n->children[k]; | |
1044 |
|
1051 | |||
1045 | if (v == 0) { |
|
1052 | if (v == 0) { | |
@@ -1059,10 +1066,10 b' static int nt_insert(indexObject *self, ' | |||||
1059 | noff = nt_new(self); |
|
1066 | noff = nt_new(self); | |
1060 | if (noff == -1) |
|
1067 | if (noff == -1) | |
1061 | return -1; |
|
1068 | return -1; | |
1062 | /* self->nt may have been changed by realloc */ |
|
1069 | /* self->nt->nodes may have been changed by realloc */ | |
1063 | self->nt[off].children[k] = noff; |
|
1070 | self->nt->nodes[off].children[k] = noff; | |
1064 | off = noff; |
|
1071 | off = noff; | |
1065 | n = &self->nt[off]; |
|
1072 | n = &self->nt->nodes[off]; | |
1066 | n->children[nt_level(oldnode, ++level)] = v; |
|
1073 | n->children[nt_level(oldnode, ++level)] = v; | |
1067 | if (level > self->ntdepth) |
|
1074 | if (level > self->ntdepth) | |
1068 | self->ntdepth = level; |
|
1075 | self->ntdepth = level; | |
@@ -1085,15 +1092,22 b' static int nt_delete_node(indexObject *s' | |||||
1085 | static int nt_init(indexObject *self) |
|
1092 | static int nt_init(indexObject *self) | |
1086 | { |
|
1093 | { | |
1087 | if (self->nt == NULL) { |
|
1094 | if (self->nt == NULL) { | |
1088 | if ((size_t)self->raw_length > INT_MAX / sizeof(nodetree)) { |
|
1095 | self->nt = PyMem_Malloc(sizeof(nodetree)); | |
|
1096 | if (self->nt == NULL) { | |||
|
1097 | PyErr_NoMemory(); | |||
|
1098 | return -1; | |||
|
1099 | } | |||
|
1100 | if ((size_t)self->raw_length > INT_MAX / sizeof(nodetreenode)) { | |||
1089 | PyErr_SetString(PyExc_ValueError, "overflow in nt_init"); |
|
1101 | PyErr_SetString(PyExc_ValueError, "overflow in nt_init"); | |
1090 | return -1; |
|
1102 | return -1; | |
1091 | } |
|
1103 | } | |
1092 | self->ntcapacity = self->raw_length < 4 |
|
1104 | self->ntcapacity = self->raw_length < 4 | |
1093 | ? 4 : (int)self->raw_length / 2; |
|
1105 | ? 4 : (int)self->raw_length / 2; | |
1094 |
|
1106 | |||
1095 | self->nt = calloc(self->ntcapacity, sizeof(nodetree)); |
|
1107 | self->nt->nodes = calloc(self->ntcapacity, sizeof(nodetreenode)); | |
1096 | if (self->nt == NULL) { |
|
1108 | if (self->nt->nodes == NULL) { | |
|
1109 | free(self->nt); | |||
|
1110 | self->nt = NULL; | |||
1097 | PyErr_NoMemory(); |
|
1111 | PyErr_NoMemory(); | |
1098 | return -1; |
|
1112 | return -1; | |
1099 | } |
|
1113 | } | |
@@ -1102,6 +1116,7 b' static int nt_init(indexObject *self)' | |||||
1102 | self->ntlookups = 1; |
|
1116 | self->ntlookups = 1; | |
1103 | self->ntmisses = 0; |
|
1117 | self->ntmisses = 0; | |
1104 | if (nt_insert(self, nullid, -1) == -1) { |
|
1118 | if (nt_insert(self, nullid, -1) == -1) { | |
|
1119 | free(self->nt->nodes); | |||
1105 | free(self->nt); |
|
1120 | free(self->nt); | |
1106 | self->nt = NULL; |
|
1121 | self->nt = NULL; | |
1107 | return -1; |
|
1122 | return -1; | |
@@ -1258,7 +1273,7 b' static int nt_shortest(indexObject *self' | |||||
1258 |
|
1273 | |||
1259 | for (level = off = 0; level < 40; level++) { |
|
1274 | for (level = off = 0; level < 40; level++) { | |
1260 | int k, v; |
|
1275 | int k, v; | |
1261 | nodetree *n = &self->nt[off]; |
|
1276 | nodetreenode *n = &self->nt->nodes[off]; | |
1262 | k = nt_level(node, level); |
|
1277 | k = nt_level(node, level); | |
1263 | v = n->children[k]; |
|
1278 | v = n->children[k]; | |
1264 | if (v < 0) { |
|
1279 | if (v < 0) { |
General Comments 0
You need to be logged in to leave comments.
Login now