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>