Annotation of embedaddon/bird/lib/slists.c, revision 1.1.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>