Annotation of embedaddon/bird/lib/slists.c, revision 1.1
1.1 ! misho 1: /*
! 2: * BIRD Library -- Safe Linked Lists
! 3: *
! 4: * (c) 1998 Martin Mares <mj@ucw.cz>
! 5: *
! 6: * Can be freely distributed and used under the terms of the GNU GPL.
! 7: */
! 8:
! 9: #define _BIRD_SLISTS_C_
! 10:
! 11: #include "nest/bird.h"
! 12: #include "lib/slists.h"
! 13:
! 14: static inline void
! 15: s_merge(snode *from, snode *to)
! 16: {
! 17: siterator *f, *g;
! 18:
! 19: if (!(f = from->readers))
! 20: return;
! 21: if (!(g = to->readers))
! 22: {
! 23: /* Fast path */
! 24: to->readers = f;
! 25: f->prev = (siterator *) to;
! 26: fixup:
! 27: while (f && f->node)
! 28: {
! 29: f->node = NULL;
! 30: f = f->next;
! 31: }
! 32: return;
! 33: }
! 34: /* Really merging */
! 35: while (g->next)
! 36: g = g->next;
! 37: g->next = f;
! 38: f->prev = g;
! 39: goto fixup;
! 40: }
! 41:
! 42: snode *
! 43: s_get(siterator *i)
! 44: {
! 45: siterator *f, *g;
! 46: snode *n;
! 47:
! 48: if (!(n = i->node))
! 49: {
! 50: /*
! 51: * No node found. We have to walk the iterator list backwards
! 52: * to find where are we linked.
! 53: */
! 54: f = i;
! 55: while (!f->null)
! 56: f = f->prev;
! 57: n = (snode *) f;
! 58: }
! 59: f = i->prev; /* Maybe the snode itself */
! 60: g = i->next;
! 61: f->next = g;
! 62: if (g)
! 63: g->prev = f;
! 64:
! 65: i->prev = NULL;
! 66: i->next = NULL;
! 67: return n;
! 68: }
! 69:
! 70: void
! 71: s_put(siterator *i, snode *n)
! 72: {
! 73: siterator *f;
! 74:
! 75: i->node = n;
! 76: if (f = n->readers)
! 77: f->prev = i;
! 78: i->next = f;
! 79: n->readers = i;
! 80: i->prev = (siterator *) n;
! 81: i->null = NULL;
! 82: }
! 83:
! 84: void
! 85: s_add_tail(slist *l, snode *n)
! 86: {
! 87: snode *z = l->tail;
! 88:
! 89: n->next = (snode *) &l->null;
! 90: n->prev = z;
! 91: z->next = n;
! 92: l->tail = n;
! 93: n->readers = NULL;
! 94: }
! 95:
! 96: void
! 97: s_add_head(slist *l, snode *n)
! 98: {
! 99: snode *z = l->head;
! 100:
! 101: n->next = z;
! 102: n->prev = (snode *) &l->head;
! 103: z->prev = n;
! 104: l->head = n;
! 105: n->readers = NULL;
! 106: }
! 107:
! 108: void
! 109: s_insert_node(snode *n, snode *after)
! 110: {
! 111: snode *z = after->next;
! 112:
! 113: n->next = z;
! 114: n->prev = after;
! 115: after->next = n;
! 116: z->prev = n;
! 117: n->readers = NULL;
! 118: }
! 119:
! 120: void
! 121: s_rem_node(snode *n)
! 122: {
! 123: snode *z = n->prev;
! 124: snode *x = n->next;
! 125:
! 126: z->next = x;
! 127: x->prev = z;
! 128: s_merge(n, x);
! 129: }
! 130:
! 131: void
! 132: s_init_list(slist *l)
! 133: {
! 134: l->head = (snode *) &l->null;
! 135: l->null = NULL;
! 136: l->tail = (snode *) &l->head;
! 137: l->tail_readers = NULL;
! 138: }
! 139:
! 140: void
! 141: s_add_tail_list(slist *to, slist *l)
! 142: {
! 143: snode *p = to->tail;
! 144: snode *q = l->head;
! 145:
! 146: p->next = q;
! 147: q->prev = p;
! 148: q = l->tail;
! 149: q->next = (snode *) &to->null;
! 150: to->tail = q;
! 151: s_merge((snode *) &l->null, (snode *) &to->null);
! 152: }
! 153:
! 154: #ifdef TEST
! 155:
! 156: #include "lib/resource.h"
! 157: #include <stdio.h>
! 158:
! 159: void dump(char *c, slist *a)
! 160: {
! 161: snode *x;
! 162:
! 163: puts(c);
! 164: for(x=SHEAD(*a); x; x=x->next)
! 165: {
! 166: siterator *i, *j;
! 167: printf("%p", x);
! 168: j = (siterator *) x;
! 169: for(i=x->readers; i; i=i->next)
! 170: {
! 171: if (i->prev != j)
! 172: printf(" ???");
! 173: j = i;
! 174: printf(" [%p:%p]", i, i->node);
! 175: }
! 176: putchar('\n');
! 177: }
! 178: puts("---");
! 179: }
! 180:
! 181: int main(void)
! 182: {
! 183: slist a, b;
! 184: snode *x, *y;
! 185: siterator i, j;
! 186:
! 187: s_init_list(&a);
! 188: s_init_list(&b);
! 189: x = xmalloc(sizeof(*x));
! 190: s_add_tail(&a, x);
! 191: x = xmalloc(sizeof(*x));
! 192: s_add_tail(&a, x);
! 193: x = xmalloc(sizeof(*x));
! 194: s_add_tail(&a, x);
! 195: dump("1", &a);
! 196:
! 197: s_init(&i, &a);
! 198: s_init(&j, &a);
! 199: dump("2", &a);
! 200:
! 201: x = s_get(&i);
! 202: printf("Got %p\n", x);
! 203: dump("3", &a);
! 204:
! 205: s_put(&i, x->next);
! 206: dump("4", &a);
! 207:
! 208: y = s_get(&j);
! 209: while (y)
! 210: {
! 211: s_put(&j, y);
! 212: dump("5*", &a);
! 213: y = s_get(&j)->next;
! 214: }
! 215:
! 216: dump("5 done", &a);
! 217:
! 218: s_rem_node(a.head->next);
! 219: dump("6 (deletion)", &a);
! 220:
! 221: s_put(&i, s_get(&i)->next);
! 222: dump("6 (relink)", &a);
! 223:
! 224: x = xmalloc(sizeof(*x));
! 225: s_add_tail(&b, x);
! 226: dump("7 (second list)", &b);
! 227:
! 228: s_add_tail_list(&b, &a);
! 229: dump("8 (after merge)", &b);
! 230:
! 231: return 0;
! 232: }
! 233:
! 234: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>