##// END OF EJS Templates
index: extract a type for the nodetree...
Martin von Zweigbergk -
r38948:d1bc0e7c default
parent child Browse files
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 self->ntcapacity * sizeof(nodetree));
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