Patchwork D4108: index: extract a type for the nodetree

login
register
mail settings
Submitter phabricator
Date Aug. 6, 2018, 1:13 p.m.
Message ID <f2d801d18296eb0903f6b3ce40a22dd6@localhost.localdomain>
Download mbox | patch
Permalink /patch/33316/
State Not Applicable
Headers show

Comments

phabricator - Aug. 6, 2018, 1:13 p.m.
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGd1bc0e7c862b: index: extract a type for the nodetree (authored by martinvonz, committed by ).

CHANGED PRIOR TO COMMIT
  https://phab.mercurial-scm.org/D4108?vs=9911&id=9972#toc

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4108?vs=9911&id=9972

REVISION DETAIL
  https://phab.mercurial-scm.org/D4108

AFFECTED FILES
  mercurial/cext/revlog.c

CHANGE DETAILS




To: martinvonz, #hg-reviewers
Cc: yuja, mercurial-devel

Patch

diff --git a/mercurial/cext/revlog.c b/mercurial/cext/revlog.c
--- a/mercurial/cext/revlog.c
+++ b/mercurial/cext/revlog.c
@@ -28,15 +28,19 @@ 
 #define PyInt_AsLong PyLong_AsLong
 #endif
 
+typedef struct {
+	int children[16];
+} nodetreenode;
+
 /*
  * A base-16 trie for fast node->rev mapping.
  *
  * Positive value is index of the next node in the trie
  * Negative value is a leaf: -(rev + 2)
  * Zero is empty
  */
 typedef struct {
-	int children[16];
+	nodetreenode *nodes;
 } nodetree;
 
 /*
@@ -317,7 +321,10 @@ 
 		PyMem_Free(self->offsets);
 		self->offsets = NULL;
 	}
-	free(self->nt);
+	if (self->nt != NULL) {
+		free(self->nt->nodes);
+		free(self->nt);
+	}
 	self->nt = NULL;
 	Py_CLEAR(self->headrevs);
 }
@@ -984,7 +991,7 @@ 
 
 	for (level = off = 0; level < maxlevel; level++) {
 		int k = getnybble(node, level);
-		nodetree *n = &self->nt[off];
+		nodetreenode *n = &self->nt->nodes[off];
 		int v = n->children[k];
 
 		if (v < 0) {
@@ -1011,20 +1018,20 @@ 
 static int nt_new(indexObject *self)
 {
 	if (self->ntlength == self->ntcapacity) {
-		if (self->ntcapacity >= INT_MAX / (sizeof(nodetree) * 2)) {
+		if (self->ntcapacity >= INT_MAX / (sizeof(nodetreenode) * 2)) {
 			PyErr_SetString(PyExc_MemoryError,
 					"overflow in nt_new");
 			return -1;
 		}
 		self->ntcapacity *= 2;
-		self->nt = realloc(self->nt,
-				   self->ntcapacity * sizeof(nodetree));
-		if (self->nt == NULL) {
+		self->nt->nodes = realloc(self->nt->nodes,
+					  self->ntcapacity * sizeof(nodetreenode));
+		if (self->nt->nodes == NULL) {
 			PyErr_SetString(PyExc_MemoryError, "out of memory");
 			return -1;
 		}
-		memset(&self->nt[self->ntlength], 0,
-		       sizeof(nodetree) * (self->ntcapacity - self->ntlength));
+		memset(&self->nt->nodes[self->ntlength], 0,
+		       sizeof(nodetreenode) * (self->ntcapacity - self->ntlength));
 	}
 	return self->ntlength++;
 }
@@ -1036,10 +1043,10 @@ 
 
 	while (level < 40) {
 		int k = nt_level(node, level);
-		nodetree *n;
+		nodetreenode *n;
 		int v;
 
-		n = &self->nt[off];
+		n = &self->nt->nodes[off];
 		v = n->children[k];
 
 		if (v == 0) {
@@ -1059,10 +1066,10 @@ 
 			noff = nt_new(self);
 			if (noff == -1)
 				return -1;
-			/* self->nt may have been changed by realloc */
-			self->nt[off].children[k] = noff;
+			/* self->nt->nodes may have been changed by realloc */
+			self->nt->nodes[off].children[k] = noff;
 			off = noff;
-			n = &self->nt[off];
+			n = &self->nt->nodes[off];
 			n->children[nt_level(oldnode, ++level)] = v;
 			if (level > self->ntdepth)
 				self->ntdepth = level;
@@ -1085,23 +1092,31 @@ 
 static int nt_init(indexObject *self)
 {
 	if (self->nt == NULL) {
-		if ((size_t)self->raw_length > INT_MAX / sizeof(nodetree)) {
+		self->nt = PyMem_Malloc(sizeof(nodetree));
+		if (self->nt == NULL) {
+			PyErr_NoMemory();
+			return -1;
+		}
+		if ((size_t)self->raw_length > INT_MAX / sizeof(nodetreenode)) {
 			PyErr_SetString(PyExc_ValueError, "overflow in nt_init");
 			return -1;
 		}
 		self->ntcapacity = self->raw_length < 4
 			? 4 : (int)self->raw_length / 2;
 
-		self->nt = calloc(self->ntcapacity, sizeof(nodetree));
-		if (self->nt == NULL) {
+		self->nt->nodes = calloc(self->ntcapacity, sizeof(nodetreenode));
+		if (self->nt->nodes == NULL) {
+			free(self->nt);
+			self->nt = NULL;
 			PyErr_NoMemory();
 			return -1;
 		}
 		self->ntlength = 1;
 		self->ntrev = (int)index_length(self);
 		self->ntlookups = 1;
 		self->ntmisses = 0;
 		if (nt_insert(self, nullid, -1) == -1) {
+			free(self->nt->nodes);
 			free(self->nt);
 			self->nt = NULL;
 			return -1;
@@ -1258,7 +1273,7 @@ 
 
 	for (level = off = 0; level < 40; level++) {
 		int k, v;
-		nodetree *n = &self->nt[off];
+		nodetreenode *n = &self->nt->nodes[off];
 		k = nt_level(node, level);
 		v = n->children[k];
 		if (v < 0) {