avlnode_insertnode.c (998B)
1 /* ISC license. */ 2 3 #include <stdint.h> 4 5 #include <skalibs/avlnode.h> 6 #include "avlnode-internal.h" 7 8 uint32_t avlnode_insertnode (avlnode *s, uint32_t max, uint32_t r, uint32_t i, dtok_func_ref dtok, cmp_func_ref f, void *p) 9 { 10 uint32_t stack[AVLNODE_MAXDEPTH] ; 11 uint8_t spin[AVLNODE_MAXDEPTH] ; 12 uint8_t sp = 0 ; 13 14 { 15 void const *k = (*dtok)(s[i].data, p) ; 16 for (; r < max ; sp++) 17 { 18 spin[sp] = avlnode_ufroms((*f)(k, (*dtok)(s[r].data, p), p)) ; 19 stack[sp] = r ; 20 r = s[r].child[spin[sp]] ; 21 } 22 } 23 r = i ; 24 while (sp--) 25 { 26 s[stack[sp]].child[spin[sp]] = r ; 27 r = stack[sp] ; 28 if (s[r].balance) goto lastfix ; 29 s[r].balance = avlnode_sfromu(spin[sp]) ; 30 } 31 return r ; 32 33 lastfix: 34 if (avlnode_ufroms(s[r].balance) != spin[sp]) 35 { 36 s[r].balance = 0 ; 37 return stack[0] ; 38 } 39 r = avlnode_rotate_maydouble(s, max, r, !spin[sp], spin[sp] != spin[sp+1]) ; 40 if (!sp--) return r ; 41 s[stack[sp]].child[spin[sp]] = r ; 42 return stack[0] ; 43 }