Mercurial > hg
comparison mercurial/cext/revlog.c @ 38846:f738c502e43b
index: store nullrev as -1 in nodetree
Nothing important, it just seems more natural to not map nullrev to
INT_MAX. We just need to change the revision encoding a little to make
space for the -1.
Differential Revision: https://phab.mercurial-scm.org/D4005
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 20 Jul 2018 22:26:28 -0700 |
parents | f9fc59ea3135 |
children | f3d394ea17db |
comparison
equal
deleted
inserted
replaced
38845:f9fc59ea3135 | 38846:f738c502e43b |
---|---|
30 | 30 |
31 /* | 31 /* |
32 * A base-16 trie for fast node->rev mapping. | 32 * A base-16 trie for fast node->rev mapping. |
33 * | 33 * |
34 * Positive value is index of the next node in the trie | 34 * Positive value is index of the next node in the trie |
35 * Negative value is a leaf: -(rev + 1) | 35 * Negative value is a leaf: -(rev + 2) |
36 * Zero is empty | 36 * Zero is empty |
37 */ | 37 */ |
38 typedef struct { | 38 typedef struct { |
39 int children[16]; | 39 int children[16]; |
40 } nodetree; | 40 } nodetree; |
229 static const char *index_node(indexObject *self, Py_ssize_t pos) | 229 static const char *index_node(indexObject *self, Py_ssize_t pos) |
230 { | 230 { |
231 Py_ssize_t length = index_length(self); | 231 Py_ssize_t length = index_length(self); |
232 const char *data; | 232 const char *data; |
233 | 233 |
234 if (pos == length - 1 || pos == INT_MAX) | 234 if (pos == length - 1 || pos == -1) |
235 return nullid; | 235 return nullid; |
236 | 236 |
237 if (pos >= length) | 237 if (pos >= length) |
238 return NULL; | 238 return NULL; |
239 | 239 |
1006 | 1006 |
1007 if (v < 0) { | 1007 if (v < 0) { |
1008 const char *n; | 1008 const char *n; |
1009 Py_ssize_t i; | 1009 Py_ssize_t i; |
1010 | 1010 |
1011 v = -(v + 1); | 1011 v = -(v + 2); |
1012 n = index_node(self, v); | 1012 n = index_node(self, v); |
1013 if (n == NULL) | 1013 if (n == NULL) |
1014 return -2; | 1014 return -2; |
1015 for (i = level; i < maxlevel; i++) | 1015 for (i = level; i < maxlevel; i++) |
1016 if (getnybble(node, i) != nt_level(n, i)) | 1016 if (getnybble(node, i) != nt_level(n, i)) |
1058 | 1058 |
1059 n = &self->nt[off]; | 1059 n = &self->nt[off]; |
1060 v = n->children[k]; | 1060 v = n->children[k]; |
1061 | 1061 |
1062 if (v == 0) { | 1062 if (v == 0) { |
1063 n->children[k] = -rev - 1; | 1063 n->children[k] = -rev - 2; |
1064 return 0; | 1064 return 0; |
1065 } | 1065 } |
1066 if (v < 0) { | 1066 if (v < 0) { |
1067 const char *oldnode = index_node_existing(self, -(v + 1)); | 1067 const char *oldnode = index_node_existing(self, -(v + 2)); |
1068 int noff; | 1068 int noff; |
1069 | 1069 |
1070 if (oldnode == NULL) | 1070 if (oldnode == NULL) |
1071 return -1; | 1071 return -1; |
1072 if (!memcmp(oldnode, node, 20)) { | 1072 if (!memcmp(oldnode, node, 20)) { |
1073 n->children[k] = -rev - 1; | 1073 n->children[k] = -rev - 2; |
1074 return 0; | 1074 return 0; |
1075 } | 1075 } |
1076 noff = nt_new(self); | 1076 noff = nt_new(self); |
1077 if (noff == -1) | 1077 if (noff == -1) |
1078 return -1; | 1078 return -1; |
1093 return -1; | 1093 return -1; |
1094 } | 1094 } |
1095 | 1095 |
1096 static int nt_delete_node(indexObject *self, const char *node) | 1096 static int nt_delete_node(indexObject *self, const char *node) |
1097 { | 1097 { |
1098 /* rev==-1 happens to get encoded as 0, which is interpreted as not set */ | 1098 /* rev==-2 happens to get encoded as 0, which is interpreted as not set */ |
1099 return nt_insert(self, node, -1); | 1099 return nt_insert(self, node, -2); |
1100 } | 1100 } |
1101 | 1101 |
1102 static int nt_init(indexObject *self) | 1102 static int nt_init(indexObject *self) |
1103 { | 1103 { |
1104 if (self->nt == NULL) { | 1104 if (self->nt == NULL) { |
1116 } | 1116 } |
1117 self->ntlength = 1; | 1117 self->ntlength = 1; |
1118 self->ntrev = (int)index_length(self) - 1; | 1118 self->ntrev = (int)index_length(self) - 1; |
1119 self->ntlookups = 1; | 1119 self->ntlookups = 1; |
1120 self->ntmisses = 0; | 1120 self->ntmisses = 0; |
1121 if (nt_insert(self, nullid, INT_MAX) == -1) { | 1121 if (nt_insert(self, nullid, -1) == -1) { |
1122 free(self->nt); | 1122 free(self->nt); |
1123 self->nt = NULL; | 1123 self->nt = NULL; |
1124 return -1; | 1124 return -1; |
1125 } | 1125 } |
1126 } | 1126 } |
1288 nodetree *n = &self->nt[off]; | 1288 nodetree *n = &self->nt[off]; |
1289 k = nt_level(node, level); | 1289 k = nt_level(node, level); |
1290 v = n->children[k]; | 1290 v = n->children[k]; |
1291 if (v < 0) { | 1291 if (v < 0) { |
1292 const char *n; | 1292 const char *n; |
1293 v = -(v + 1); | 1293 v = -(v + 2); |
1294 n = index_node_existing(self, v); | 1294 n = index_node_existing(self, v); |
1295 if (n == NULL) | 1295 if (n == NULL) |
1296 return -3; | 1296 return -3; |
1297 if (memcmp(node, n, 20) != 0) | 1297 if (memcmp(node, n, 20) != 0) |
1298 /* | 1298 /* |