Merge branch 'jt/decorate-api'
A few structures and variables that are implementation details of the decorate API have been renamed and then the API got documented better. * jt/decorate-api: decorate: clean up and document API
This commit is contained in:
commit
eacf669cec
@ -1,6 +0,0 @@
|
|||||||
decorate API
|
|
||||||
============
|
|
||||||
|
|
||||||
Talk about <decorate.h>
|
|
||||||
|
|
||||||
(Linus)
|
|
1
Makefile
1
Makefile
@ -651,6 +651,7 @@ TEST_PROGRAMS_NEED_X += test-dump-cache-tree
|
|||||||
TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
|
TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
|
||||||
TEST_PROGRAMS_NEED_X += test-dump-split-index
|
TEST_PROGRAMS_NEED_X += test-dump-split-index
|
||||||
TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
|
TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
|
||||||
|
TEST_PROGRAMS_NEED_X += test-example-decorate
|
||||||
TEST_PROGRAMS_NEED_X += test-fake-ssh
|
TEST_PROGRAMS_NEED_X += test-fake-ssh
|
||||||
TEST_PROGRAMS_NEED_X += test-genrandom
|
TEST_PROGRAMS_NEED_X += test-genrandom
|
||||||
TEST_PROGRAMS_NEED_X += test-hashmap
|
TEST_PROGRAMS_NEED_X += test-hashmap
|
||||||
|
@ -895,7 +895,7 @@ static void export_marks(char *file)
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint32_t mark;
|
uint32_t mark;
|
||||||
struct object_decoration *deco = idnums.hash;
|
struct decoration_entry *deco = idnums.entries;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int e = 0;
|
int e = 0;
|
||||||
|
|
||||||
|
28
decorate.c
28
decorate.c
@ -14,20 +14,20 @@ static unsigned int hash_obj(const struct object *obj, unsigned int n)
|
|||||||
static void *insert_decoration(struct decoration *n, const struct object *base, void *decoration)
|
static void *insert_decoration(struct decoration *n, const struct object *base, void *decoration)
|
||||||
{
|
{
|
||||||
int size = n->size;
|
int size = n->size;
|
||||||
struct object_decoration *hash = n->hash;
|
struct decoration_entry *entries = n->entries;
|
||||||
unsigned int j = hash_obj(base, size);
|
unsigned int j = hash_obj(base, size);
|
||||||
|
|
||||||
while (hash[j].base) {
|
while (entries[j].base) {
|
||||||
if (hash[j].base == base) {
|
if (entries[j].base == base) {
|
||||||
void *old = hash[j].decoration;
|
void *old = entries[j].decoration;
|
||||||
hash[j].decoration = decoration;
|
entries[j].decoration = decoration;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
if (++j >= size)
|
if (++j >= size)
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
hash[j].base = base;
|
entries[j].base = base;
|
||||||
hash[j].decoration = decoration;
|
entries[j].decoration = decoration;
|
||||||
n->nr++;
|
n->nr++;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -36,24 +36,23 @@ static void grow_decoration(struct decoration *n)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int old_size = n->size;
|
int old_size = n->size;
|
||||||
struct object_decoration *old_hash = n->hash;
|
struct decoration_entry *old_entries = n->entries;
|
||||||
|
|
||||||
n->size = (old_size + 1000) * 3 / 2;
|
n->size = (old_size + 1000) * 3 / 2;
|
||||||
n->hash = xcalloc(n->size, sizeof(struct object_decoration));
|
n->entries = xcalloc(n->size, sizeof(struct decoration_entry));
|
||||||
n->nr = 0;
|
n->nr = 0;
|
||||||
|
|
||||||
for (i = 0; i < old_size; i++) {
|
for (i = 0; i < old_size; i++) {
|
||||||
const struct object *base = old_hash[i].base;
|
const struct object *base = old_entries[i].base;
|
||||||
void *decoration = old_hash[i].decoration;
|
void *decoration = old_entries[i].decoration;
|
||||||
|
|
||||||
if (!decoration)
|
if (!decoration)
|
||||||
continue;
|
continue;
|
||||||
insert_decoration(n, base, decoration);
|
insert_decoration(n, base, decoration);
|
||||||
}
|
}
|
||||||
free(old_hash);
|
free(old_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a decoration pointer, return any old one */
|
|
||||||
void *add_decoration(struct decoration *n, const struct object *obj,
|
void *add_decoration(struct decoration *n, const struct object *obj,
|
||||||
void *decoration)
|
void *decoration)
|
||||||
{
|
{
|
||||||
@ -64,7 +63,6 @@ void *add_decoration(struct decoration *n, const struct object *obj,
|
|||||||
return insert_decoration(n, obj, decoration);
|
return insert_decoration(n, obj, decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup a decoration pointer */
|
|
||||||
void *lookup_decoration(struct decoration *n, const struct object *obj)
|
void *lookup_decoration(struct decoration *n, const struct object *obj)
|
||||||
{
|
{
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
@ -74,7 +72,7 @@ void *lookup_decoration(struct decoration *n, const struct object *obj)
|
|||||||
return NULL;
|
return NULL;
|
||||||
j = hash_obj(obj, n->size);
|
j = hash_obj(obj, n->size);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct object_decoration *ref = n->hash + j;
|
struct decoration_entry *ref = n->entries + j;
|
||||||
if (ref->base == obj)
|
if (ref->base == obj)
|
||||||
return ref->decoration;
|
return ref->decoration;
|
||||||
if (!ref->base)
|
if (!ref->base)
|
||||||
|
49
decorate.h
49
decorate.h
@ -1,18 +1,61 @@
|
|||||||
#ifndef DECORATE_H
|
#ifndef DECORATE_H
|
||||||
#define DECORATE_H
|
#define DECORATE_H
|
||||||
|
|
||||||
struct object_decoration {
|
/*
|
||||||
|
* A data structure that associates Git objects to void pointers. See
|
||||||
|
* t/helper/test-example-decorate.c for a demonstration of how to use these
|
||||||
|
* functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An entry in the data structure.
|
||||||
|
*/
|
||||||
|
struct decoration_entry {
|
||||||
const struct object *base;
|
const struct object *base;
|
||||||
void *decoration;
|
void *decoration;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The data structure.
|
||||||
|
*
|
||||||
|
* This data structure must be zero-initialized.
|
||||||
|
*/
|
||||||
struct decoration {
|
struct decoration {
|
||||||
|
/*
|
||||||
|
* Not used by the decoration mechanism. Clients may use this for
|
||||||
|
* whatever they want.
|
||||||
|
*/
|
||||||
const char *name;
|
const char *name;
|
||||||
unsigned int size, nr;
|
|
||||||
struct object_decoration *hash;
|
/*
|
||||||
|
* The capacity of "entries".
|
||||||
|
*/
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The number of real Git objects (that is, entries with non-NULL
|
||||||
|
* "base").
|
||||||
|
*/
|
||||||
|
unsigned int nr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The entries. This is an array of size "size", containing nr entries
|
||||||
|
* with non-NULL "base" and (size - nr) entries with NULL "base".
|
||||||
|
*/
|
||||||
|
struct decoration_entry *entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an association from the given object to the given pointer (which may be
|
||||||
|
* NULL), returning the previously associated pointer. If there is no previous
|
||||||
|
* association, this function returns NULL.
|
||||||
|
*/
|
||||||
extern void *add_decoration(struct decoration *n, const struct object *obj, void *decoration);
|
extern void *add_decoration(struct decoration *n, const struct object *obj, void *decoration);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the pointer associated to the given object. If there is no
|
||||||
|
* association, this function returns NULL.
|
||||||
|
*/
|
||||||
extern void *lookup_decoration(struct decoration *n, const struct object *obj);
|
extern void *lookup_decoration(struct decoration *n, const struct object *obj);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1
t/helper/.gitignore
vendored
1
t/helper/.gitignore
vendored
@ -8,6 +8,7 @@
|
|||||||
/test-dump-fsmonitor
|
/test-dump-fsmonitor
|
||||||
/test-dump-split-index
|
/test-dump-split-index
|
||||||
/test-dump-untracked-cache
|
/test-dump-untracked-cache
|
||||||
|
/test-example-decorate
|
||||||
/test-fake-ssh
|
/test-fake-ssh
|
||||||
/test-scrap-cache-tree
|
/test-scrap-cache-tree
|
||||||
/test-genrandom
|
/test-genrandom
|
||||||
|
74
t/helper/test-example-decorate.c
Normal file
74
t/helper/test-example-decorate.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "cache.h"
|
||||||
|
#include "object.h"
|
||||||
|
#include "decorate.h"
|
||||||
|
|
||||||
|
int cmd_main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
struct decoration n;
|
||||||
|
struct object_id one_oid = { {1} };
|
||||||
|
struct object_id two_oid = { {2} };
|
||||||
|
struct object_id three_oid = { {3} };
|
||||||
|
struct object *one, *two, *three;
|
||||||
|
|
||||||
|
int decoration_a, decoration_b;
|
||||||
|
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
int i, objects_noticed = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The struct must be zero-initialized.
|
||||||
|
*/
|
||||||
|
memset(&n, 0, sizeof(n));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add 2 objects, one with a non-NULL decoration and one with a NULL
|
||||||
|
* decoration.
|
||||||
|
*/
|
||||||
|
one = lookup_unknown_object(one_oid.hash);
|
||||||
|
two = lookup_unknown_object(two_oid.hash);
|
||||||
|
ret = add_decoration(&n, one, &decoration_a);
|
||||||
|
if (ret)
|
||||||
|
die("BUG: when adding a brand-new object, NULL should be returned");
|
||||||
|
ret = add_decoration(&n, two, NULL);
|
||||||
|
if (ret)
|
||||||
|
die("BUG: when adding a brand-new object, NULL should be returned");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When re-adding an already existing object, the old decoration is
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
ret = add_decoration(&n, one, NULL);
|
||||||
|
if (ret != &decoration_a)
|
||||||
|
die("BUG: when readding an already existing object, existing decoration should be returned");
|
||||||
|
ret = add_decoration(&n, two, &decoration_b);
|
||||||
|
if (ret)
|
||||||
|
die("BUG: when readding an already existing object, existing decoration should be returned");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookup returns the added declarations, or NULL if the object was
|
||||||
|
* never added.
|
||||||
|
*/
|
||||||
|
ret = lookup_decoration(&n, one);
|
||||||
|
if (ret)
|
||||||
|
die("BUG: lookup should return added declaration");
|
||||||
|
ret = lookup_decoration(&n, two);
|
||||||
|
if (ret != &decoration_b)
|
||||||
|
die("BUG: lookup should return added declaration");
|
||||||
|
three = lookup_unknown_object(three_oid.hash);
|
||||||
|
ret = lookup_decoration(&n, three);
|
||||||
|
if (ret)
|
||||||
|
die("BUG: lookup for unknown object should return NULL");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The user can also loop through all entries.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < n.size; i++) {
|
||||||
|
if (n.entries[i].base)
|
||||||
|
objects_noticed++;
|
||||||
|
}
|
||||||
|
if (objects_noticed != 2)
|
||||||
|
die("BUG: should have 2 objects");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
10
t/t9004-example.sh
Executable file
10
t/t9004-example.sh
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='check that example code compiles and runs'
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_expect_success 'decorate' '
|
||||||
|
test-example-decorate
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Loading…
Reference in New Issue
Block a user