git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 5/9] Add string-specific memory pool

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Jun 24, 2010, 10:58 UTC
Message-ID
<20100624105813.GE12376@burratino>
In-Reply-To
<20100624105004.GA12336@burratino>
From: David Barr <david.barr@cordelta.com>

Intern strings so they can be compared by address and stored without wasting space.

This library uses the macros in the obj_pool.h and trp.h to create a memory pool for strings and expose an API for handling them.

Signed-off-by: David Barr <david.barr@cordelta.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Makefile              |    4 +-
 vcs-svn/string_pool.c |  114 +++++++++++++++++++++++++++++++++++++++++++++++++
 vcs-svn/string_pool.h |   15 ++++++
 3 files changed, 131 insertions(+), 2 deletions(-)
 create mode 100644 vcs-svn/string_pool.c
 create mode 100644 vcs-svn/string_pool.h
diff --git a/Makefile b/Makefile
index 663a366..e11e588 100644
--- a/Makefile
+++ b/Makefile
@@ -1740,7 +1740,7 @@ ifndef NO_CURL
 endif
 XDIFF_OBJS = xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
 	xdiff/xmerge.o xdiff/xpatience.o
-VCSSVN_OBJS =
+VCSSVN_OBJS = vcs-svn/string_pool.o
 OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
 
 dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
@@ -1864,7 +1864,7 @@ xdiff-interface.o $(XDIFF_OBJS): \
 	xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h
 
 $(VCSSVN_OBJS): \
-	vcs-svn/obj_pool.h vcs-svn/trp.h
+	vcs-svn/obj_pool.h vcs-svn/trp.h vcs-svn/string_pool.h
 endif
 
 exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \
diff --git a/vcs-svn/string_pool.c b/vcs-svn/string_pool.c
new file mode 100644
index 0000000..bd5a380
--- /dev/null
+++ b/vcs-svn/string_pool.c
@@ -0,0 +1,114 @@
+/*
+ * Licensed under a two-clause BSD-style license.
+ * See LICENSE for details.
+ */
+
+#include "git-compat-util.h"
+#include "trp.h"
+#include "obj_pool.h"
+#include "string_pool.h"
+
+static struct trp_root tree = { ~0 };
+
+struct node {
+	uint32_t offset;
+	struct trp_node children;
+};
+
+/* Two memory pools: one for struct node, and another for strings */
+obj_pool_gen(node, struct node, 4096);
+obj_pool_gen(string, char, 4096);
+
+static char *node_value(struct node *node)
+{
+	return node ? string_pointer(node->offset) : NULL;
+}
+
+static int node_cmp(struct node *a, struct node *b)
+{
+	return strcmp(node_value(a), node_value(b));
+}
+
+/* Build a Treap from the node structure (a trp_node w/ offset) */
+trp_gen(static, tree_, struct node, children, node, node_cmp);
+
+char *pool_fetch(uint32_t entry)
+{
+	return node_value(node_pointer(entry));
+}
+
+uint32_t pool_intern(char *key)
+{
+	/* Canonicalize key */
+	struct node *match = NULL;
+	uint32_t key_len;
+	if (key == NULL)
+		return ~0;
+	key_len = strlen(key) + 1;
+	struct node *node = node_pointer(node_alloc(1));
+	node->offset = string_alloc(key_len);
+	strcpy(node_value(node), key);
+	match = tree_search(&tree, node);
+	if (!match) {
+		tree_insert(&tree, node);
+	} else {
+		node_free(1);
+		string_free(key_len);
+		node = match;
+	}
+	return node_offset(node);
+}
+
+uint32_t pool_tok_r(char *str, const char *delim, char **saveptr)
+{
+	char *token = strtok_r(str, delim, saveptr);
+	return token ? pool_intern(token) : ~0;
+}
+
+void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream)
+{
+	uint32_t i;
+	for (i = 0; i < len && ~seq[i]; i++) {
+		fputs(pool_fetch(seq[i]), stream);
+		if (i < len - 1 && ~seq[i + 1])
+			fputc(delim, stream);
+	}
+}
+
+uint32_t pool_tok_seq(uint32_t max, uint32_t *seq, char *delim, char *str)
+{
+	char *context = NULL;
+	uint32_t length = 0, token = str ? pool_tok_r(str, delim, &context) : ~0;
+	while (length < max) {
+		seq[length++] = token;
+		if (token == ~0)
+			break;
+		token = pool_tok_r(NULL, delim, &context);
+	}
+	seq[length ? length - 1 : 0] = ~0;
+	return length;
+}
+
+void pool_init(void)
+{
+	uint32_t node;
+	uint32_t string = 0;
+	string_init();
+	while (string < string_pool.size) {
+		node = node_alloc(1);
+		node_pointer(node)->offset = string;
+		tree_insert(&tree, node_pointer(node));
+		string += strlen(string_pointer(string)) + 1;
+	}
+}
+
+void pool_commit(void)
+{
+	string_commit();
+}
+
+void pool_reset(void)
+{
+	node_reset();
+	string_reset();
+}
diff --git a/vcs-svn/string_pool.h b/vcs-svn/string_pool.h
new file mode 100644
index 0000000..085e6d7
--- /dev/null
+++ b/vcs-svn/string_pool.h
@@ -0,0 +1,15 @@
+#ifndef STRING_POOL_H_
+#define STRING_POOL_H_
+
+#include "git-compat-util.h"
+
+uint32_t pool_intern(char *key);
+char *pool_fetch(uint32_t entry);
+uint32_t pool_tok_r(char *str, const char *delim, char **saveptr);
+void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream);
+uint32_t pool_tok_seq(uint32_t max, uint32_t *seq, char *delim, char *str);
+void pool_init(void);
+void pool_commit(void);
+void pool_reset(void);
+
+#endif
-- 
1.7.1
Previous: Jonathan NiederNext: Ramkumar Ramachandra
Message 15 of 35 in “Subversion dump parsing library”
  1. 0/9 Subversion dump parsing libraryJonathan Nieder, Jun 24, 2010
  2. 1/9 Export parse_date_basic() to convert a date string to timestampJonathan Nieder, Jun 24, 2010
  3. Ramkumar RamachandraJun 24, 2010
  4. 2/9 Introduce vcs-svn libJonathan Nieder, Jun 24, 2010
  5. Ramkumar RamachandraJun 24, 2010
  6. 3/9 Add memory pool libraryJonathan Nieder, Jun 24, 2010
  7. Ramkumar RamachandraJun 24, 2010
  8. Jonathan NiederJun 24, 2010
  9. Ramkumar RamachandraJun 24, 2010
  10. Jonathan NiederJun 24, 2010
  11. Ramkumar RamachandraJun 24, 2010
  12. 4/9 Add treap implementationJonathan Nieder, Jun 24, 2010
  13. Ramkumar RamachandraJun 24, 2010
  14. Jonathan NiederJun 24, 2010
  15. 5/9 Add string-specific memory poolJonathan Nieder, Jun 24, 2010
  16. Ramkumar RamachandraJun 24, 2010
  17. 6/9 Add stream helper libraryJonathan Nieder, Jun 24, 2010
  18. Ramkumar RamachandraJun 24, 2010
  19. Jonathan NiederJun 24, 2010
  20. 7/9 Add infrastructure to write revisions in fast-export formatJonathan Nieder, Jun 24, 2010
  21. Ramkumar RamachandraJun 24, 2010
  22. Jonathan NiederJun 24, 2010
  23. Jonathan NiederJun 24, 2010
  24. Ramkumar RamachandraJun 24, 2010
  25. 8/9 Add SVN dump parserJonathan Nieder, Jun 24, 2010
  26. Ramkumar RamachandraJun 24, 2010
  27. 9/9 Add a sample user for the svndump libraryJonathan Nieder, Jun 24, 2010
  28. Ramkumar RamachandraJun 24, 2010
  29. Jonathan NiederJun 24, 2010
  30. Ramkumar RamachandraJun 24, 2010
  31. Jonathan NiederJun 24, 2010
  32. Sam VilainJun 30, 2010
  33. Ramkumar RamachandraJun 24, 2010
  34. Jonathan NiederJun 24, 2010
  35. Jonathan NiederJun 24, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.