Skip to content

Commit ab795f0

Browse files
bk2204gitster
authored andcommitted
hash: add a function to finalize object IDs
To avoid the penalty of having to branch in hash comparison functions, we'll want to always compare the full hash member in a struct object_id, which will require that SHA-1 object IDs be zero-padded. To do so, add a function which finalizes a hash context and writes it into an object ID that performs this padding. Move the definition of struct object_id and the constant definitions higher up so we they are available for us to use. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c3b4e4e commit ab795f0

File tree

2 files changed

+52
-23
lines changed

2 files changed

+52
-23
lines changed

hash.h

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,29 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s
9595
/* Number of algorithms supported (including unknown). */
9696
#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
9797

98+
/* The length in bytes and in hex digits of an object name (SHA-1 value). */
99+
#define GIT_SHA1_RAWSZ 20
100+
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
101+
/* The block size of SHA-1. */
102+
#define GIT_SHA1_BLKSZ 64
103+
104+
/* The length in bytes and in hex digits of an object name (SHA-256 value). */
105+
#define GIT_SHA256_RAWSZ 32
106+
#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
107+
/* The block size of SHA-256. */
108+
#define GIT_SHA256_BLKSZ 64
109+
110+
/* The length in byte and in hex digits of the largest possible hash value. */
111+
#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
112+
#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
113+
/* The largest possible block size for any supported hash. */
114+
#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
115+
116+
struct object_id {
117+
unsigned char hash[GIT_MAX_RAWSZ];
118+
int algo;
119+
};
120+
98121
/* A suitably aligned type for stack allocations of hash contexts. */
99122
union git_hash_ctx {
100123
git_SHA_CTX sha1;
@@ -106,6 +129,7 @@ typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
106129
typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
107130
typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
108131
typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
132+
typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
109133

110134
struct git_hash_algo {
111135
/*
@@ -138,6 +162,9 @@ struct git_hash_algo {
138162
/* The hash finalization function. */
139163
git_hash_final_fn final_fn;
140164

165+
/* The hash finalization function for object IDs. */
166+
git_hash_final_oid_fn final_oid_fn;
167+
141168
/* The OID of the empty tree. */
142169
const struct object_id *empty_tree;
143170

@@ -161,29 +188,6 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
161188
return p - hash_algos;
162189
}
163190

164-
/* The length in bytes and in hex digits of an object name (SHA-1 value). */
165-
#define GIT_SHA1_RAWSZ 20
166-
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
167-
/* The block size of SHA-1. */
168-
#define GIT_SHA1_BLKSZ 64
169-
170-
/* The length in bytes and in hex digits of an object name (SHA-256 value). */
171-
#define GIT_SHA256_RAWSZ 32
172-
#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
173-
/* The block size of SHA-256. */
174-
#define GIT_SHA256_BLKSZ 64
175-
176-
/* The length in byte and in hex digits of the largest possible hash value. */
177-
#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
178-
#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
179-
/* The largest possible block size for any supported hash. */
180-
#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
181-
182-
struct object_id {
183-
unsigned char hash[GIT_MAX_RAWSZ];
184-
int algo;
185-
};
186-
187191
#define the_hash_algo the_repository->hash_algo
188192

189193
extern const struct object_id null_oid;

object-file.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ static void git_hash_sha1_final(unsigned char *hash, git_hash_ctx *ctx)
8989
git_SHA1_Final(hash, &ctx->sha1);
9090
}
9191

92+
static void git_hash_sha1_final_oid(struct object_id *oid, git_hash_ctx *ctx)
93+
{
94+
git_SHA1_Final(oid->hash, &ctx->sha1);
95+
memset(oid->hash + GIT_SHA1_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ);
96+
}
97+
9298

9399
static void git_hash_sha256_init(git_hash_ctx *ctx)
94100
{
@@ -110,6 +116,16 @@ static void git_hash_sha256_final(unsigned char *hash, git_hash_ctx *ctx)
110116
git_SHA256_Final(hash, &ctx->sha256);
111117
}
112118

119+
static void git_hash_sha256_final_oid(struct object_id *oid, git_hash_ctx *ctx)
120+
{
121+
git_SHA256_Final(oid->hash, &ctx->sha256);
122+
/*
123+
* This currently does nothing, so the compiler should optimize it out,
124+
* but keep it in case we extend the hash size again.
125+
*/
126+
memset(oid->hash + GIT_SHA256_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA256_RAWSZ);
127+
}
128+
113129
static void git_hash_unknown_init(git_hash_ctx *ctx)
114130
{
115131
BUG("trying to init unknown hash");
@@ -130,6 +146,12 @@ static void git_hash_unknown_final(unsigned char *hash, git_hash_ctx *ctx)
130146
BUG("trying to finalize unknown hash");
131147
}
132148

149+
static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)
150+
{
151+
BUG("trying to finalize unknown hash");
152+
}
153+
154+
133155
const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
134156
{
135157
NULL,
@@ -141,6 +163,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
141163
git_hash_unknown_clone,
142164
git_hash_unknown_update,
143165
git_hash_unknown_final,
166+
git_hash_unknown_final_oid,
144167
NULL,
145168
NULL,
146169
},
@@ -155,6 +178,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
155178
git_hash_sha1_clone,
156179
git_hash_sha1_update,
157180
git_hash_sha1_final,
181+
git_hash_sha1_final_oid,
158182
&empty_tree_oid,
159183
&empty_blob_oid,
160184
},
@@ -169,6 +193,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
169193
git_hash_sha256_clone,
170194
git_hash_sha256_update,
171195
git_hash_sha256_final,
196+
git_hash_sha256_final_oid,
172197
&empty_tree_oid_sha256,
173198
&empty_blob_oid_sha256,
174199
}

0 commit comments

Comments
 (0)