зеркало из https://github.com/microsoft/git.git
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:
Коммит
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-split-index
|
||||
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-genrandom
|
||||
TEST_PROGRAMS_NEED_X += test-hashmap
|
||||
|
|
|
@ -895,7 +895,7 @@ static void export_marks(char *file)
|
|||
{
|
||||
unsigned int i;
|
||||
uint32_t mark;
|
||||
struct object_decoration *deco = idnums.hash;
|
||||
struct decoration_entry *deco = idnums.entries;
|
||||
FILE *f;
|
||||
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)
|
||||
{
|
||||
int size = n->size;
|
||||
struct object_decoration *hash = n->hash;
|
||||
struct decoration_entry *entries = n->entries;
|
||||
unsigned int j = hash_obj(base, size);
|
||||
|
||||
while (hash[j].base) {
|
||||
if (hash[j].base == base) {
|
||||
void *old = hash[j].decoration;
|
||||
hash[j].decoration = decoration;
|
||||
while (entries[j].base) {
|
||||
if (entries[j].base == base) {
|
||||
void *old = entries[j].decoration;
|
||||
entries[j].decoration = decoration;
|
||||
return old;
|
||||
}
|
||||
if (++j >= size)
|
||||
j = 0;
|
||||
}
|
||||
hash[j].base = base;
|
||||
hash[j].decoration = decoration;
|
||||
entries[j].base = base;
|
||||
entries[j].decoration = decoration;
|
||||
n->nr++;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -36,24 +36,23 @@ static void grow_decoration(struct decoration *n)
|
|||
{
|
||||
int i;
|
||||
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->hash = xcalloc(n->size, sizeof(struct object_decoration));
|
||||
n->entries = xcalloc(n->size, sizeof(struct decoration_entry));
|
||||
n->nr = 0;
|
||||
|
||||
for (i = 0; i < old_size; i++) {
|
||||
const struct object *base = old_hash[i].base;
|
||||
void *decoration = old_hash[i].decoration;
|
||||
const struct object *base = old_entries[i].base;
|
||||
void *decoration = old_entries[i].decoration;
|
||||
|
||||
if (!decoration)
|
||||
continue;
|
||||
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 *decoration)
|
||||
{
|
||||
|
@ -64,7 +63,6 @@ void *add_decoration(struct decoration *n, const struct object *obj,
|
|||
return insert_decoration(n, obj, decoration);
|
||||
}
|
||||
|
||||
/* Lookup a decoration pointer */
|
||||
void *lookup_decoration(struct decoration *n, const struct object *obj)
|
||||
{
|
||||
unsigned int j;
|
||||
|
@ -74,7 +72,7 @@ void *lookup_decoration(struct decoration *n, const struct object *obj)
|
|||
return NULL;
|
||||
j = hash_obj(obj, n->size);
|
||||
for (;;) {
|
||||
struct object_decoration *ref = n->hash + j;
|
||||
struct decoration_entry *ref = n->entries + j;
|
||||
if (ref->base == obj)
|
||||
return ref->decoration;
|
||||
if (!ref->base)
|
||||
|
|
49
decorate.h
49
decorate.h
|
@ -1,18 +1,61 @@
|
|||
#ifndef 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;
|
||||
void *decoration;
|
||||
};
|
||||
|
||||
/*
|
||||
* The data structure.
|
||||
*
|
||||
* This data structure must be zero-initialized.
|
||||
*/
|
||||
struct decoration {
|
||||
/*
|
||||
* Not used by the decoration mechanism. Clients may use this for
|
||||
* whatever they want.
|
||||
*/
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
/test-dump-fsmonitor
|
||||
/test-dump-split-index
|
||||
/test-dump-untracked-cache
|
||||
/test-example-decorate
|
||||
/test-fake-ssh
|
||||
/test-scrap-cache-tree
|
||||
/test-genrandom
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче