📄 ind_ins.c
字号:
idm = ++((struct p_head *) asp)->idmod; a = asp + sizeof (struct p_head); b = asp + indph->ind_off; recmjform (OLD, seg_n, pn, idm, a - asp, b - a, a, 0); bcopy (mas, asp + indphsize, n1); if (nels != 0) mod_nels ((-nels), asp + lnbeg); indph->ind_off = n1 + indphsize; indph->ind_nextpn = newpn; assert (check_ind_page (asp) == 0); putwul (&pg, 'm'); asp = getnew (&pg, seg_n, newpn); /* get newpn without lock */ indph = (struct ind_page *) asp; nkey = lastb - lbeg + size2b; indph->ind_off = indphsize; b = pereliv (asp, 0, nels, nkey, mas + n1, massz - n1); indph->ind_off = b - asp; indph->ind_nextpn = (u2_t) ~0; indph->ind_wpage = BTWN; assert (check_ind_page (asp) == 0); putwul (&pg, 'm'); /* put page without unlock */ return (0);}inticp_insrtn (struct ldesind *desind, char *key, char *key2, char *inf, i4_t infsz){ i4_t lagelsz, agelsz, sz, off, ans, ans_lk; u2_t rootpn, d_fn; char *asp = NULL, *lastb, *bbeg, *loc; struct ind_page *indph; i4_t idm; struct A pg; thread_s_ini_check(); seg_n = desind->i_segn; afn = (u2_t *) (desind + 1); k_n = desind->ldi.kifn & ~UNIQ & MSK21B; uniq_key = UNIQ & desind->ldi.kifn; d_f = desind->pdf; d_fn = k_n; if ((k_n % 2) != 0) d_fn += 1; d_f2 = (struct des_field *) (afn + d_fn); k2sz = d_f2->field_size; inf_size = infsz; lagelsz = k2sz + infsz; agelsz = k2sz + size2b; rootpn = desind->ldi.rootpn; beg_mop ();try_again: while ((asp = getpg (&pg, seg_n, rootpn, 's')) == NULL); /* Lock and request */ thread_s_ini(); thread_s_put (rootpn); indph = (struct ind_page *) asp; if (indph->ind_wpage == LEAF) { /* root-leaf */ off = indph->ind_off; lastb = asp + off; sz = insrep (asp, lastb, key, key2, lagelsz, &bbeg, &loc); if (sz == 0) { putpg (&pg, 'n'); thread_s_ini(); return (NU); } if (BD_PAGESIZE - off < sz) { if (inroot (&pg, sz, key, key2, inf, bbeg, loc, LEAF) < 0) goto try_again; } else { if (lenforce ()< 0) { all_unlock (); goto try_again; } idm = ++((struct p_head *) asp)->idmod; icp_insrec (key, key2, inf, infsz, bbeg, loc, lastb, rootpn, asp, idm); loc = (char *) &indph->ind_off; recmjform (OLD, seg_n, rootpn, idm, loc - asp, size2b, loc, 0); indph->ind_off += sz; assert (check_ind_page (asp) == 0); putwul (&pg, 'm'); } } else { if ((ans = icp_spusk (&pg, agelsz, key, key2)) == -1) { all_unlock (); goto try_again; } else if (ans == 1) { if ((ans_lk = largest_key (&pg, key, key2, inf, LEAF)) < 0) { all_unlock (); goto try_again; } else if (ans_lk == 1) { putpg (&pg, 'n'); all_unlock (); thread_s_ini(); return (NU); } } else { /* for the leaf */ asp = pg.p_shm; indph = (struct ind_page *) asp; off = indph->ind_off; lastb = asp + off; sz = insrep (asp, lastb, key, key2, lagelsz, &bbeg, &loc); if (sz == 0) { putpg (&pg, 'n'); all_unlock (); thread_s_ini(); return (NU); } if (BD_PAGESIZE - off < sz) { if (rbrobr (&pg, sz, key, key2, inf, bbeg, loc) < 0) goto try_again; } else { assert (loc != lastb); upunlock (); if (lenforce ()< 0) { all_unlock (); goto try_again; } idm = ++((struct p_head *) asp)->idmod; icp_insrec (key, key2, inf, infsz, bbeg, loc, lastb, pg.p_pn, asp, idm); loc = (char *) &indph->ind_off; recmjform (OLD, seg_n, pg.p_pn, idm, loc - asp, size2b, loc, 0); indph->ind_off += sz; assert (check_ind_page (asp) == 0); putwul (&pg, 'm'); } } } MJ_PUTBL (); downunlock (); thread_s_ini(); return (OK);}inticp_spusk (struct A *pg, i4_t elsz, char *key, char *key2){ char *a, *lastb, *asp; u2_t n, pn; i4_t l, l2=0, ksz, i; struct ind_page *indph; asp = pg->p_shm; indph = (struct ind_page *)asp; lastb = asp + indph->ind_off; a = asp + indphsize; for (i = 0; indph->ind_wpage != LEAF; i++) { lastb = asp + indph->ind_off; for (a = asp + indphsize; a < lastb; ) { n = t2bunpack (a); assert (n < BD_PAGESIZE / 2); a += size2b; ksz = kszcal (a, afn, d_f); if ((l = cmpkeys (k_n, afn, d_f, a, key)) == 0) { a += ksz; for (; n != 0; n--, a += elsz) if ((l2 = cmp2keys (d_f2->field_type, a, key2)) >= 0) break; if (n == 0 && l2 < 0) { if (a == lastb) assert (indph->ind_nextpn == (u2_t) ~0); continue; } if (n == 0) a -= elsz; break; } else if (l > 0) { a += ksz; break; } a += ksz + n * elsz; } if (a == lastb) { assert (i==0); if ((asp = find_largest_key (pg)) == NULL) return (-1); return (1); } a += k2sz; pn = t2bunpack (a); putwul (pg, 'n'); if ((asp = getpg (pg, seg_n, pn, 's')) == NULL) return (-1); thread_s_put (pn); indph = (struct ind_page *) asp; } thread_s.u = thread_s.d - 1; return (0);}intremrep (char *asp, char *key, char *key2, i4_t elsz, char ** rbeg, char **rloc, i4_t *offbef){ char *a, *lastb, *ckey, *bbeg; i4_t i, keysz, agsz = 0; u2_t n; lastb = asp + ((struct ind_page *) asp)->ind_off; for (a = asp + indphsize; a < lastb; a += agsz) { bbeg = a; n = t2bunpack (a); assert (n < BD_PAGESIZE / 2); ckey = a + size2b; keysz = kszcal (ckey, afn, d_f); if (cmpkeys (k_n, afn, d_f, ckey, key) == 0) { a += size2b + keysz; for (i = 0; i != n; i++, a += elsz) if (cmp2keys (d_f2->field_type, a, key2) == 0) { *rbeg = bbeg; *offbef = bbeg - asp - agsz; *rloc = a; if (n == 1) return (size2b + keysz + elsz); else return (elsz); } assert (i != n); } agsz = size2b + keysz + n * elsz; assert (agsz < BD_PAGESIZE); } assert (a < lastb); return (0);}voidicp_remrec (char *beg, char *loc, i4_t sz, char *lastb, i4_t elsz, u2_t pn, char *asp, i4_t idm){ char *b; i4_t size; if (sz == elsz) { b = loc + sz; size = lastb - b; if (asp != NULL) recmjform (COMBL, seg_n, pn, idm, loc - asp, size, loc, sz); bcopy (b, loc, size); if (asp != NULL) recmjform (OLD, seg_n, pn, idm, beg - asp, size2b, beg, 0); mod_nels (-1, beg); } else { b = beg + sz; size = lastb - b; if (asp != NULL) recmjform (COMBL, seg_n, pn, idm, beg - asp, size, beg, sz); bcopy (b, beg, size); }}intmlreddi (char *lkey, char *lkey2, char *lnkey, char *lnkey2, u2_t pn){ char *asp, *pnt; i4_t sz, remsz, insz, off, orbeg, orloc, oibeg, oiloc, elsz, dopsz; struct ind_page *indph; i4_t idm; struct A pg; char ninf[size2b]; t2bpack (pn, ninf); pn = *(--thread_s.u); asp = getwl (&pg, seg_n, pn); /* get pn without lock */ remsz = mlrep1 (asp, lkey, lkey2, lnkey, &orbeg, &orloc, &oibeg, &oiloc, &insz); indph = (struct ind_page *) asp; off = indph->ind_off; dopsz = insz - remsz; sz = off + dopsz; elsz = k2sz + size2b; if (sz > BD_PAGESIZE) { char *mas, *b, *beg, *loc, *lastb; i4_t massz, ans, size; massz = sz - indphsize; mas = (char *) xmalloc (massz); size = off - indphsize; bcopy (asp + indphsize, mas, size); b = mas + size; beg = mas + orbeg - indphsize; loc = mas + orloc - indphsize; icp_remrec (beg, loc, remsz, b, elsz, 0, NULL, 0); lastb = b - remsz; beg = mas + oibeg - indphsize; loc = mas + oiloc - indphsize; icp_insrec (lnkey, lnkey2, ninf, size2b, beg, loc, lastb, 0, NULL, 0); if (indph->ind_wpage == IROOT) { /* uppn is root */ ans = crnlev (&pg, mas, mas + massz, BTWN); } else { char last_key[BD_PAGESIZE]; char last_k2[BD_PAGESIZE]; u2_t rbrpn, keysz = 0 ; if (orloc + elsz != off) /* lkey isn't the last key in pn */ { FIND_LAST_KEY (asp, elsz, lkey, lkey2, keysz); } else keysz = kszcal (lkey, afn, d_f); assert ( keysz != 0 ); bcopy (lkey, last_key, keysz); bcopy (lkey2, last_k2, k2sz); rbrpn = indph->ind_nextpn; putwul (&pg, 'n'); ans = rbrup (pn, rbrpn, mas, massz, last_key, last_k2); } xfree ((void *) mas); return (ans); } if (orloc + elsz == off && indph->ind_wpage != IROOT) { putwul (&pg, 'n'); if (mlreddi (lkey, lkey2, lnkey, lnkey2, pn) < 0) return (-1); asp = getwl (&pg, seg_n, pn); } else { upunlock (); if (lenforce ()< 0) { putwul (&pg, 'n'); return (-1); } } idm = ++((struct p_head *) asp)->idmod; indph = (struct ind_page *) asp; if (orloc == oiloc) { /* keys match */ pnt = asp + orloc; recmjform (OLD, seg_n, pn, idm, orloc, k2sz, pnt, 0); bcopy (lnkey2, pnt, k2sz); } else { pnt = asp + indph->ind_off; icp_remrec (asp + orbeg, asp + orloc, remsz, pnt, elsz, pn, asp, idm); icp_insrec (lnkey, lnkey2, ninf, size2b, asp + oibeg, asp + oiloc, pnt - remsz, pn, asp, idm); } if (dopsz != 0) { pnt = (char *) &indph->ind_off; recmjform (OLD, seg_n, pn, idm, pnt - asp, size2b, pnt, 0); indph->ind_off += dopsz; } assert (check_ind_page (asp) == 0); putwul (&pg, 'm'); /* put page without unlock */ return (0);}intmodlast (char *key, char *key2, char *nkey, char *nkey2, u2_t pn){ char *lastb, *asp, *beg, *loc; struct ind_page *indph; i4_t sz = 0, remsz = 0, elsz, off; i4_t orbeg, orloc, oibeg, oiloc; i4_t idm; struct A pg; char ninf[size2b]; t2bpack (pn, ninf); pn = *(--thread_s.u); asp = getwl (&pg, seg_n, pn); /* get uppn without lock */ indph = (struct ind_page *) asp; off = indph->ind_off; elsz = k2sz + size2b; if (key != nkey) { if (cmpkeys (k_n, afn, d_f, key, nkey) == 0) nkey = key; else { i4_t insz; remsz = mlrep1 (asp, key, key2, nkey, &orbeg, &orloc, &oibeg, &oiloc, &insz); assert (insz != 0); sz = insz - remsz; if (sz + off > BD_PAGESIZE) { char *mas; i4_t massz, ans; massz = off + insz - indphsize; mas = (char *) xmalloc (massz); sz = off - indphsize; bcopy (asp + indphsize, mas, sz); lastb = mas + sz; icp_remrec (mas + orbeg, mas + orloc, remsz, lastb, elsz, 0, NULL, 0); lastb -= remsz; icp_insrec (nkey, nkey2, ninf, size2b, mas + oibeg, mas + oiloc, lastb, 0, NULL, 0); if (indph->ind_wpage != IROOT) { putwul (&pg, 'n'); ans = divsn_modlast (key, key2, pn, mas, massz); } else ans = crnlev (&pg, mas, mas + massz, BTWN); xfree ((void *) mas); return (ans); } } } if (indph->ind_wpage != IROOT) { /* pn is not root */ putwul (&pg, 'n'); if (modlast (key, key2, nkey, nkey2, pn) < 0) return (-1); asp = getwl (&pg, seg_n, pn); /* get pn without lock */ indph = (struct ind_page *) asp; } else { upunlock (); if (lenforce ()< 0) { putwul (&pg, 'n'); return (-1); } } idm = ++((struct p_head *) asp)->idmod; lastb = asp + off; if (key == nkey) { loc = lastb - elsz; recmjform (OLD, seg_n, pn, idm, loc - asp, size2b, loc, 0); bcopy (nkey2, loc, k2sz); } else { beg = asp + orbeg; loc = asp + orloc; icp_remrec (beg, loc, remsz, lastb, elsz, pn, asp, idm); lastb -= remsz; beg = asp + oibeg; loc = asp + oiloc; icp_insrec (nkey, nkey2, ninf, size2b, beg, loc, lastb, pn, asp, idm); } if (sz != 0) { char *a; a = (char *) &indph->ind_off; recmjform (OLD, seg_n, pn, idm, a - asp, size2b, a, 0); indph->ind_off += sz; } assert (check_ind_page (asp) == 0); putwul (&pg, 'm'); return (0);}voidall_unlock (){ BUF_unlock (seg_n, thread_s.count, thread_s.arr);}voidupunlock (){ i4_t i; i = thread_s.u - thread_s.arr; if (i) BUF_unlock (seg_n, i, thread_s.arr);}voiddownunlock (){ i4_t i; i = thread_s.d - thread_s.u; if (i) BUF_unlock (seg_n, i, thread_s.u);}intlenforce (){ u2_t *a; for (a = thread_s.u; a < thread_s.d; a++) if (BUF_enforce (seg_n, *a) < 0) { downunlock (); return (-1); } return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -