mirror of
https://github.com/git/git.git
synced 2024-11-27 12:03:55 +08:00
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 <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
c3b4e4ee36
commit
ab795f0d77
50
hash.h
50
hash.h
@ -95,6 +95,29 @@ static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *s
|
||||
/* Number of algorithms supported (including unknown). */
|
||||
#define GIT_HASH_NALGOS (GIT_HASH_SHA256 + 1)
|
||||
|
||||
/* The length in bytes and in hex digits of an object name (SHA-1 value). */
|
||||
#define GIT_SHA1_RAWSZ 20
|
||||
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
|
||||
/* The block size of SHA-1. */
|
||||
#define GIT_SHA1_BLKSZ 64
|
||||
|
||||
/* The length in bytes and in hex digits of an object name (SHA-256 value). */
|
||||
#define GIT_SHA256_RAWSZ 32
|
||||
#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
|
||||
/* The block size of SHA-256. */
|
||||
#define GIT_SHA256_BLKSZ 64
|
||||
|
||||
/* The length in byte and in hex digits of the largest possible hash value. */
|
||||
#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
|
||||
#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
|
||||
/* The largest possible block size for any supported hash. */
|
||||
#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
|
||||
|
||||
struct object_id {
|
||||
unsigned char hash[GIT_MAX_RAWSZ];
|
||||
int algo;
|
||||
};
|
||||
|
||||
/* A suitably aligned type for stack allocations of hash contexts. */
|
||||
union git_hash_ctx {
|
||||
git_SHA_CTX sha1;
|
||||
@ -106,6 +129,7 @@ typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
|
||||
typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
|
||||
typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
|
||||
typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
|
||||
typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx);
|
||||
|
||||
struct git_hash_algo {
|
||||
/*
|
||||
@ -138,6 +162,9 @@ struct git_hash_algo {
|
||||
/* The hash finalization function. */
|
||||
git_hash_final_fn final_fn;
|
||||
|
||||
/* The hash finalization function for object IDs. */
|
||||
git_hash_final_oid_fn final_oid_fn;
|
||||
|
||||
/* The OID of the empty tree. */
|
||||
const struct object_id *empty_tree;
|
||||
|
||||
@ -161,29 +188,6 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
|
||||
return p - hash_algos;
|
||||
}
|
||||
|
||||
/* The length in bytes and in hex digits of an object name (SHA-1 value). */
|
||||
#define GIT_SHA1_RAWSZ 20
|
||||
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)
|
||||
/* The block size of SHA-1. */
|
||||
#define GIT_SHA1_BLKSZ 64
|
||||
|
||||
/* The length in bytes and in hex digits of an object name (SHA-256 value). */
|
||||
#define GIT_SHA256_RAWSZ 32
|
||||
#define GIT_SHA256_HEXSZ (2 * GIT_SHA256_RAWSZ)
|
||||
/* The block size of SHA-256. */
|
||||
#define GIT_SHA256_BLKSZ 64
|
||||
|
||||
/* The length in byte and in hex digits of the largest possible hash value. */
|
||||
#define GIT_MAX_RAWSZ GIT_SHA256_RAWSZ
|
||||
#define GIT_MAX_HEXSZ GIT_SHA256_HEXSZ
|
||||
/* The largest possible block size for any supported hash. */
|
||||
#define GIT_MAX_BLKSZ GIT_SHA256_BLKSZ
|
||||
|
||||
struct object_id {
|
||||
unsigned char hash[GIT_MAX_RAWSZ];
|
||||
int algo;
|
||||
};
|
||||
|
||||
#define the_hash_algo the_repository->hash_algo
|
||||
|
||||
extern const struct object_id null_oid;
|
||||
|
@ -89,6 +89,12 @@ static void git_hash_sha1_final(unsigned char *hash, git_hash_ctx *ctx)
|
||||
git_SHA1_Final(hash, &ctx->sha1);
|
||||
}
|
||||
|
||||
static void git_hash_sha1_final_oid(struct object_id *oid, git_hash_ctx *ctx)
|
||||
{
|
||||
git_SHA1_Final(oid->hash, &ctx->sha1);
|
||||
memset(oid->hash + GIT_SHA1_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ);
|
||||
}
|
||||
|
||||
|
||||
static void git_hash_sha256_init(git_hash_ctx *ctx)
|
||||
{
|
||||
@ -110,6 +116,16 @@ static void git_hash_sha256_final(unsigned char *hash, git_hash_ctx *ctx)
|
||||
git_SHA256_Final(hash, &ctx->sha256);
|
||||
}
|
||||
|
||||
static void git_hash_sha256_final_oid(struct object_id *oid, git_hash_ctx *ctx)
|
||||
{
|
||||
git_SHA256_Final(oid->hash, &ctx->sha256);
|
||||
/*
|
||||
* This currently does nothing, so the compiler should optimize it out,
|
||||
* but keep it in case we extend the hash size again.
|
||||
*/
|
||||
memset(oid->hash + GIT_SHA256_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA256_RAWSZ);
|
||||
}
|
||||
|
||||
static void git_hash_unknown_init(git_hash_ctx *ctx)
|
||||
{
|
||||
BUG("trying to init unknown hash");
|
||||
@ -130,6 +146,12 @@ static void git_hash_unknown_final(unsigned char *hash, git_hash_ctx *ctx)
|
||||
BUG("trying to finalize unknown hash");
|
||||
}
|
||||
|
||||
static void git_hash_unknown_final_oid(struct object_id *oid, git_hash_ctx *ctx)
|
||||
{
|
||||
BUG("trying to finalize unknown hash");
|
||||
}
|
||||
|
||||
|
||||
const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
|
||||
{
|
||||
NULL,
|
||||
@ -141,6 +163,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
|
||||
git_hash_unknown_clone,
|
||||
git_hash_unknown_update,
|
||||
git_hash_unknown_final,
|
||||
git_hash_unknown_final_oid,
|
||||
NULL,
|
||||
NULL,
|
||||
},
|
||||
@ -155,6 +178,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
|
||||
git_hash_sha1_clone,
|
||||
git_hash_sha1_update,
|
||||
git_hash_sha1_final,
|
||||
git_hash_sha1_final_oid,
|
||||
&empty_tree_oid,
|
||||
&empty_blob_oid,
|
||||
},
|
||||
@ -169,6 +193,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
|
||||
git_hash_sha256_clone,
|
||||
git_hash_sha256_update,
|
||||
git_hash_sha256_final,
|
||||
git_hash_sha256_final_oid,
|
||||
&empty_tree_oid_sha256,
|
||||
&empty_blob_oid_sha256,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user