Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
commit-slab: introduce slabname##_peek() function
There is no API to ask "Does this commit have associated data in
slab?".  If an application wants to (1) parse just a few commits at
the beginning of a process, (2) store data for only these commits,
and then (3) start processing many commits, taking into account the
data stored (for a few of them) in the slab, the application would
use slabname##_at() to allocate a space to store data in (2), but
there is no API other than slabname##_at() to use in step (3).  This
allocates and wastes new space for these commits the caller is only
interested in checking if they have data stored in step (2).

Introduce slabname##_peek(), which is similar to slabname##_at() but
returns NULL when there is no data already associated to it in such
a use case.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Junio C Hamano committed May 22, 2015
1 parent 282616c commit 862e730
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
34 changes: 29 additions & 5 deletions commit-slab.h
Expand Up @@ -15,7 +15,13 @@
* - int *indegree_at(struct indegree *, struct commit *);
*
* This function locates the data associated with the given commit in
* the indegree slab, and returns the pointer to it.
* the indegree slab, and returns the pointer to it. The location to
* store the data is allocated as necessary.
*
* - int *indegree_peek(struct indegree *, struct commit *);
*
* This function is similar to indegree_at(), but it will return NULL
* until a call to indegree_at() was made for the commit.
*
* - void init_indegree(struct indegree *);
* void init_indegree_with_stride(struct indegree *, int);
Expand Down Expand Up @@ -80,8 +86,9 @@ static MAYBE_UNUSED void clear_ ##slabname(struct slabname *s) \
s->slab = NULL; \
} \
\
static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
const struct commit *c) \
static MAYBE_UNUSED elemtype *slabname## _at_peek(struct slabname *s, \
const struct commit *c, \
int add_if_missing) \
{ \
int nth_slab, nth_slot; \
\
Expand All @@ -90,17 +97,34 @@ static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
\
if (s->slab_count <= nth_slab) { \
int i; \
if (!add_if_missing) \
return NULL; \
s->slab = xrealloc(s->slab, \
(nth_slab + 1) * sizeof(*s->slab)); \
stat_ ##slabname## realloc++; \
for (i = s->slab_count; i <= nth_slab; i++) \
s->slab[i] = NULL; \
s->slab_count = nth_slab + 1; \
} \
if (!s->slab[nth_slab]) \
if (!s->slab[nth_slab]) { \
if (!add_if_missing) \
return NULL; \
s->slab[nth_slab] = xcalloc(s->slab_size, \
sizeof(**s->slab) * s->stride); \
return &s->slab[nth_slab][nth_slot * s->stride]; \
} \
return &s->slab[nth_slab][nth_slot * s->stride]; \
} \
\
static MAYBE_UNUSED elemtype *slabname## _at(struct slabname *s, \
const struct commit *c) \
{ \
return slabname##_at_peek(s, c, 1); \
} \
\
static MAYBE_UNUSED elemtype *slabname## _peek(struct slabname *s, \
const struct commit *c) \
{ \
return slabname##_at_peek(s, c, 0); \
} \
\
static int stat_ ##slabname## realloc
Expand Down
28 changes: 20 additions & 8 deletions commit.c
Expand Up @@ -244,7 +244,12 @@ void set_commit_buffer(struct commit *commit, void *buffer, unsigned long size)

const void *get_cached_commit_buffer(const struct commit *commit, unsigned long *sizep)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
if (!v) {
if (sizep)
*sizep = 0;
return NULL;
}
if (sizep)
*sizep = v->size;
return v->buffer;
Expand All @@ -271,24 +276,31 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)

void unuse_commit_buffer(const struct commit *commit, const void *buffer)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
if (v->buffer != buffer)
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
if (!(v && v->buffer == buffer))
free((void *)buffer);
}

void free_commit_buffer(struct commit *commit)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
free(v->buffer);
v->buffer = NULL;
v->size = 0;
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
if (v) {
free(v->buffer);
v->buffer = NULL;
v->size = 0;
}
}

const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
{
struct commit_buffer *v = buffer_slab_at(&buffer_slab, commit);
struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
void *ret;

if (!v) {
if (sizep)
*sizep = 0;
return NULL;
}
ret = v->buffer;
if (sizep)
*sizep = v->size;
Expand Down

0 comments on commit 862e730

Please sign in to comment.