Commit 838f22df authored by Niels Möller's avatar Niels Möller
Browse files

Added linked-list implementation.

Rev: src/alist.c:1.4
Rev: src/alist.h:1.4
parent 4b059d21
......@@ -32,16 +32,16 @@
#include "atoms.h"
#include "xalloc.h"
struct alist_table
struct alist_linear
{
struct alist super;
void *table[NUMBER_OF_ATOMS];
};
static void *do_get(struct alist *c, int atom)
static void *do_linear_get(struct alist *c, int atom)
{
struct alist_table *closure = (struct alist_table *) c;
struct alist_linear *closure = (struct alist_linear *) c;
assert(atom >= 0);
assert(atom < NUMBER_OF_ATOMS);
......@@ -51,25 +51,33 @@ static void *do_get(struct alist *c, int atom)
return closure->table[atom];
}
static void do_set(struct alist *c, int atom, void *value)
static void do_linear_set(struct alist *c, int atom, void *value)
{
struct alist_table *closure = (struct alist_table *) c;
struct alist_linear *closure = (struct alist_linear *) c;
assert(atom >= 0);
assert(atom < NUMBER_OF_ATOMS);
MDEBUG(closure);
#if ALIST_USE_SIZE
size += !closure->table[atom] - !value;
#endif
closure->table[atom] = value;
}
struct alist *make_alist(int n, ...)
struct alist *make_linear_alist(int n, ...)
{
int i;
va_list args;
struct alist_table *res = xalloc(sizeof(struct alist_table));
struct alist_linear *res = xalloc(sizeof(struct alist_linear));
#if ALIST_USE_SIZE
res->size = 0;
#endif
for (i = 0; i<NUMBER_OF_ATOMS; i++)
res->table[i] = NULL;
......@@ -80,13 +88,134 @@ struct alist *make_alist(int n, ...)
int atom = va_arg(args, int);
void *value = va_arg(args, void *);
#if ALIST_USE_SIZE
if (!value)
res->size ++;
#endif
res->table[atom] = value;
}
assert(va_arg(args, int) == -1);
res->super.get = do_get;
res->super.set = do_set;
res->super.get = do_linear_get;
res->super.set = do_linear_set;
return &res->super;
}
struct node
{
struct node *next;
int atom;
void *value;
};
struct alist_linked
{
struct alist super;
struct node *head;
};
static void *do_linked_get(struct alist *c, int atom)
{
struct alist_linked *closure = (struct alist_linked *) c;
struct node *p;
assert(atom >= 0);
assert(atom < NUMBER_OF_ATOMS);
MDEBUG(closure);
for (p = self->first; p; p = p->next)
if (p->atom == atom)
return p->value;
return NULL;
}
static void do_linked_set(struct alist *c, int atom, void *value)
{
struct alist_linked *closure = (struct alist_linked *) c;
assert(atom >= 0);
assert(atom < NUMBER_OF_ATOMS);
MDEBUG(closure);
if (value)
{
struct node *p;
for (p = self->first; p; p = p->next)
if (p->atom == atom)
{
p->value = value;
return;
}
p = xalloc(sizeof(struct node));
p->next = self->first;
p->atom = atom;
p->value = value;
self->first = p;
#if ALIST_USE_SIZE
self->size++;
#endif
}
else
{ /* Remove atom */
struct node **p;
for(p = &self->first; *p; )
{
struct node *o = *p;
if (o->atom = atom)
{
*p = o->next;
lsh_free(o);
self->size--;
return;
}
p = &o->next;
}
/* Not found */
}
}
struct alist *make_linked_alist(int n, ...)
{
int i;
va_list args;
struct alist_linked *self = xalloc(sizeof(struct alist_linked));
struct alist *res = &self->super;
#if ALIST_USE_SIZE
self->size = 0;
#endif
self->first = NULL;
va_start(args, n);
for (i=0, p = NULL; i<n; i++)
{
int atom = va_arg(args, int);
void *value = va_arg(args, void *);
do_linked_set(res, atom, value);
}
assert(va_arg(args, int) == -1);
res->get = do_linked_get;
res->set = do_linked_set;
return res;
}
......@@ -28,21 +28,36 @@
#include "lsh_types.h"
#define ALIST_USE_SIZE 0
/* Abstract interface allows for multiple implementations ("real"
* alists, linear tables, hash tables */
struct alist
{
struct lsh_object header;
#if ALIST_USE_SIZE
int size; /* Number of associations with non-zero values */
int * (*keys)(struct alist *self);
#endif
void * (*get)(struct alist *self, int atom);
void (*set)(struct alist *self, int atom, void *value);
};
#define ALIST_GET(alist, atom) ((alist)->get((alist), (atom)))
#define ALIST_SET(alist, atom, value) ((alist)->set((alist), (atom), (value)))
#if ALIST_USE_SIZE
#define ALIST_KEYS(alist) ((alist)->keys((alist)))
#endif
/* n is the number of pairs. The argument list should be terminated
* with -1, for sanity checks. */
struct alist *make_alist(int n, ...);
struct alist *make_linear_alist(int n, ...);
struct alist *make_linked_alist(int n, ...);
#define make_alist make_linear_alist
#endif /* LSH_ALIST_H_INCLUDED */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment