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

[PATCH 6/6] Automatically switch to crc32 checksum for index when it's too large

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 6, 2012, 05:48 UTC
Message-ID
<1328507319-24687-6-git-send-email-pclouds@gmail.com>
In-Reply-To
<1328507319-24687-1-git-send-email-pclouds@gmail.com>

An experiment with -O3 is done on Intel D510@1.66GHz. At around 250k entries, index reading time exceeds 0.5s. Switching to crc32 brings it back lower than 0.2s.

On 4M files index, reading time with SHA-1 takes ~8.4, crc32 2.8s.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 I know no real repositories this size though. gentoo-x86 is "only"
 120k. Haven't checked libreoffice repo yet.
 On 2M files index, allocating one big block (i.e. reverting debed2a
 (read-cache.c: allocate index entries individually - 2011-10-24)
 saves about 0.3s. Maybe we can allocate one big block, then malloc
 separately when the block is fully used.
 Writing time is still high. "git update-index --crc32" on crc32 250k index
 takes 0.9s (so writing time is about 0.5s)
 A better solution may be narrow clone (or just the narrow checkout
 part), where index only contains entries from checked out
 subdirectories.
 Documentation/config.txt |    7 +++++++
 builtin/update-index.c   |    1 +
 cache.h                  |    1 +
 config.c                 |    5 +++++
 environment.c            |    1 +
 read-cache.c             |    8 ++++++++
 6 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index abeb82b..55b7596 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -540,6 +540,13 @@ relatively high IO latencies.  With this set to 'true', git will do the
 index comparison to the filesystem data in parallel, allowing
 overlapping IO's.
 
+core.crc32IndexThreshold::
+	Usually SHA-1 is used to check for index integerity. When the
+	number of entries in index exceeds this threshold, crc32 will
+	be used instead. Zero means SHA-1 always be used. Negative
+	value disables this threshold (i.e. crc32 or SHA-1 is decided
+	by other means).
+
 core.createObject::
 	You can set this to 'link', in which case a hardlink followed by
 	a delete of the source are used to make sure that object creation
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 6913226..5cb51c7 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -856,6 +856,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
 	argc = parse_options_end(&ctx);
 
 	if (do_crc != -1) {
+		core_crc32_index_threshold = -1;
 		if (do_crc)
 			the_index.hdr_flags |= CACHE_F_CRC;
 		else
diff --git a/cache.h b/cache.h
index 7352402..d05856b 100644
--- a/cache.h
+++ b/cache.h
@@ -610,6 +610,7 @@ extern unsigned long pack_size_limit_cfg;
 extern int read_replace_refs;
 extern int fsync_object_files;
 extern int core_preload_index;
+extern int core_crc32_index_threshold;
 extern int core_apply_sparse_checkout;
 
 enum branch_track {
diff --git a/config.c b/config.c
index 40f9c6d..905e071 100644
--- a/config.c
+++ b/config.c
@@ -671,6 +671,11 @@ static int git_default_core_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.crc32indexthreshold")) {
+		core_crc32_index_threshold = git_config_int(var, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "core.createobject")) {
 		if (!strcmp(value, "rename"))
 			object_creation_mode = OBJECT_CREATION_USES_RENAMES;
diff --git a/environment.c b/environment.c
index c93b8f4..9d9dfc2 100644
--- a/environment.c
+++ b/environment.c
@@ -66,6 +66,7 @@ unsigned long pack_size_limit_cfg;
 
 /* Parallel index stat data preload? */
 int core_preload_index = 0;
+int core_crc32_index_threshold = 250000;
 
 /* This is set by setup_git_dir_gently() and/or git_default_config() */
 char *git_work_tree_cfg;
diff --git a/read-cache.c b/read-cache.c
index a34878e..fd032d8 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1582,6 +1582,14 @@ int write_index(struct index_state *istate, int newfd)
 		}
 	}
 
+	if (core_crc32_index_threshold >= 0) {
+		if (core_crc32_index_threshold > 0 &&
+		    istate->cache_nr >= core_crc32_index_threshold)
+			istate->hdr_flags |= CACHE_F_CRC;
+		else
+			istate->hdr_flags &= ~CACHE_F_CRC;
+	}
+
 	hdr.h.hdr_signature = htonl(CACHE_SIGNATURE);
 	if (istate->hdr_flags) {
 		hdr.h.hdr_version = htonl(4);
-- 
1.7.8.36.g69ee2
Previous: Dave ZarzyckiNext: Dave Zarzycki
Message 15 of 20 in “read-cache: use sha1file for sha1 calculation”
  1. 1/6 read-cache: use sha1file for sha1 calculationNguyễn Thái Ngọc Duy, Feb 6, 2012
  2. 2/6 csum-file: make sha1 calculation optionalNguyễn Thái Ngọc Duy, Feb 6, 2012
  3. 3/6 Stop producing index version 2Nguyễn Thái Ngọc Duy, Feb 6, 2012
  4. Junio C HamanoFeb 6, 2012
  5. Shawn PearceFeb 7, 2012
  6. Nguyen Thai Ngoc DuyFeb 7, 2012
  7. Nguyen Thai Ngoc DuyFeb 7, 2012
  8. Junio C HamanoFeb 7, 2012
  9. Thomas RastFeb 7, 2012
  10. 4/6 Introduce index version 4 with global flagsNguyễn Thái Ngọc Duy, Feb 6, 2012
  11. 5/6 Allow to use crc32 as a lighter checksum on indexNguyễn Thái Ngọc Duy, Feb 6, 2012
  12. Shawn PearceFeb 7, 2012
  13. Dave ZarzyckiFeb 7, 2012
  14. Dave ZarzyckiFeb 7, 2012
  15. 6/6 Automatically switch to crc32 checksum for index when it's too largeNguyễn Thái Ngọc Duy, Feb 6, 2012
  16. Dave ZarzyckiFeb 6, 2012
  17. Nguyen Thai Ngoc DuyFeb 6, 2012
  18. Dave ZarzyckiFeb 6, 2012
  19. Junio C HamanoFeb 6, 2012
  20. Nguyen Thai Ngoc DuyFeb 6, 2012

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.