Skip to content

Commit a941d5e

Browse files
peffgitster
authored andcommitted
introduce notes-cache interface
Notes provide a fast lookup mechanism for data keyed by sha1. This is ideal for caching certain operations, like textconv filters. This patch builds some infrastructure to make it simpler to use notes trees as caches. In particular, caches: 1. don't have arbitrary commit messages. They store a cache validity string in the commit, and clear the tree when the cache validity string changes. 2. don't keep any commit history. The accumulated history of a a cache is just useless cruft. 3. use a looser form of locking for ref updates. If two processes try to write to the cache simultaneously, it is OK if one overwrites the other, losing some changes. It's just a cache, so we will just end up with an extra miss. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 40d52ff commit a941d5e

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ LIB_H += log-tree.h
486486
LIB_H += mailmap.h
487487
LIB_H += merge-recursive.h
488488
LIB_H += notes.h
489+
LIB_H += notes-cache.h
489490
LIB_H += object.h
490491
LIB_H += pack.h
491492
LIB_H += pack-refs.h
@@ -575,6 +576,7 @@ LIB_OBJS += merge-file.o
575576
LIB_OBJS += merge-recursive.o
576577
LIB_OBJS += name-hash.o
577578
LIB_OBJS += notes.o
579+
LIB_OBJS += notes-cache.o
578580
LIB_OBJS += object.o
579581
LIB_OBJS += pack-check.o
580582
LIB_OBJS += pack-refs.o

notes-cache.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "cache.h"
2+
#include "notes-cache.h"
3+
#include "commit.h"
4+
#include "refs.h"
5+
6+
static int notes_cache_match_validity(const char *ref, const char *validity)
7+
{
8+
unsigned char sha1[20];
9+
struct commit *commit;
10+
struct pretty_print_context pretty_ctx;
11+
struct strbuf msg = STRBUF_INIT;
12+
int ret;
13+
14+
if (read_ref(ref, sha1) < 0)
15+
return 0;
16+
17+
commit = lookup_commit_reference_gently(sha1, 1);
18+
if (!commit)
19+
return 0;
20+
21+
memset(&pretty_ctx, 0, sizeof(pretty_ctx));
22+
format_commit_message(commit, "%s", &msg, &pretty_ctx);
23+
strbuf_trim(&msg);
24+
25+
ret = !strcmp(msg.buf, validity);
26+
strbuf_release(&msg);
27+
28+
return ret;
29+
}
30+
31+
void notes_cache_init(struct notes_cache *c, const char *name,
32+
const char *validity)
33+
{
34+
struct strbuf ref = STRBUF_INIT;
35+
int flags = 0;
36+
37+
memset(c, 0, sizeof(*c));
38+
c->validity = xstrdup(validity);
39+
40+
strbuf_addf(&ref, "refs/notes/%s", name);
41+
if (!notes_cache_match_validity(ref.buf, validity))
42+
flags = NOTES_INIT_EMPTY;
43+
init_notes(&c->tree, ref.buf, combine_notes_overwrite, flags);
44+
strbuf_release(&ref);
45+
}
46+
47+
int notes_cache_write(struct notes_cache *c)
48+
{
49+
unsigned char tree_sha1[20];
50+
unsigned char commit_sha1[20];
51+
52+
if (!c || !c->tree.initialized || !c->tree.ref || !*c->tree.ref)
53+
return -1;
54+
if (!c->tree.dirty)
55+
return 0;
56+
57+
if (write_notes_tree(&c->tree, tree_sha1))
58+
return -1;
59+
if (commit_tree(c->validity, tree_sha1, NULL, commit_sha1, NULL) < 0)
60+
return -1;
61+
if (update_ref("update notes cache", c->tree.ref, commit_sha1, NULL,
62+
0, QUIET_ON_ERR) < 0)
63+
return -1;
64+
65+
return 0;
66+
}
67+
68+
char *notes_cache_get(struct notes_cache *c, unsigned char key_sha1[20],
69+
size_t *outsize)
70+
{
71+
const unsigned char *value_sha1;
72+
enum object_type type;
73+
char *value;
74+
unsigned long size;
75+
76+
value_sha1 = get_note(&c->tree, key_sha1);
77+
if (!value_sha1)
78+
return NULL;
79+
value = read_sha1_file(value_sha1, &type, &size);
80+
81+
*outsize = size;
82+
return value;
83+
}
84+
85+
int notes_cache_put(struct notes_cache *c, unsigned char key_sha1[20],
86+
const char *data, size_t size)
87+
{
88+
unsigned char value_sha1[20];
89+
90+
if (write_sha1_file(data, size, "blob", value_sha1) < 0)
91+
return -1;
92+
add_note(&c->tree, key_sha1, value_sha1, NULL);
93+
return 0;
94+
}

notes-cache.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef NOTES_CACHE_H
2+
#define NOTES_CACHE_H
3+
4+
#include "notes.h"
5+
6+
struct notes_cache {
7+
struct notes_tree tree;
8+
char *validity;
9+
};
10+
11+
void notes_cache_init(struct notes_cache *c, const char *name,
12+
const char *validity);
13+
int notes_cache_write(struct notes_cache *c);
14+
15+
char *notes_cache_get(struct notes_cache *c, unsigned char sha1[20], size_t
16+
*outsize);
17+
int notes_cache_put(struct notes_cache *c, unsigned char sha1[20],
18+
const char *data, size_t size);
19+
20+
#endif /* NOTES_CACHE_H */

0 commit comments

Comments
 (0)