/* * Returns: * 0 ==> OK * -1 ==> Error */ int __split_page(HTAB *hashp, uint32_t obucket, uint32_t nbucket) { BUFHEAD *new_bufp, *old_bufp; uint16_t *ino; char *np; DBT key, val; int n, ndx, retval; uint16_t copyto, diff, off, moved; char *op; size_t temp; copyto = (uint16_t)hashp->BSIZE; off = (uint16_t)hashp->BSIZE; old_bufp = __get_buf(hashp, obucket, NULL, 0); if (old_bufp == NULL) return (-1); new_bufp = __get_buf(hashp, nbucket, NULL, 0); if (new_bufp == NULL) return (-1); old_bufp->flags |= (BUF_MOD | BUF_PIN); new_bufp->flags |= (BUF_MOD | BUF_PIN); ino = (uint16_t *)(void *)(op = old_bufp->page); np = new_bufp->page; moved = 0; for (n = 1, ndx = 1; n < ino[0]; n += 2) { if (ino[n + 1] < REAL_KEY) { retval = ugly_split(hashp, obucket, old_bufp, new_bufp, (int)copyto, (int)moved); old_bufp->flags &= ~BUF_PIN; new_bufp->flags &= ~BUF_PIN; return (retval); } key.data = (uint8_t *)op + ino[n]; key.size = off - ino[n]; if (__call_hash(hashp, key.data, (int)key.size) == obucket) { /* Don't switch page */ diff = copyto - off; if (diff) { copyto = ino[n + 1] + diff; memmove(op + copyto, op + ino[n + 1], (size_t)(off - ino[n + 1])); ino[ndx] = copyto + ino[n] - ino[n + 1]; ino[ndx + 1] = copyto; } else copyto = ino[n + 1]; ndx += 2; } else { /* Switch page */ val.data = (uint8_t *)op + ino[n + 1]; val.size = ino[n] - ino[n + 1]; putpair(np, &key, &val); moved += 2; } off = ino[n + 1]; } /* Now clean up the page */ ino[0] -= moved; temp = sizeof(uint16_t) * (ino[0] + 3); _DIAGASSERT(copyto >= temp); FREESPACE(ino) = (uint16_t)(copyto - temp); OFFSET(ino) = copyto; #ifdef DEBUG3 (void)fprintf(stderr, "split %d/%d\n", ((uint16_t *)np)[0] / 2, ((uint16_t *)op)[0] / 2); #endif /* unpin both pages */ old_bufp->flags &= ~BUF_PIN; new_bufp->flags &= ~BUF_PIN; return (0); }
/* * Returns: * 0 ==> OK * -1 ==> Error */ extern int __split_page(HTAB *hashp, uint32 obucket, uint32 nbucket) { register BUFHEAD *new_bufp, *old_bufp; register uint16 *ino; register uint16 *tmp_uint16_array; register char *np; DBT key, val; uint16 n, ndx; int retval; uint16 copyto, diff, moved; size_t off; char *op; copyto = (uint16)hashp->BSIZE; off = (uint16)hashp->BSIZE; old_bufp = __get_buf(hashp, obucket, NULL, 0); if (old_bufp == NULL) return (-1); new_bufp = __get_buf(hashp, nbucket, NULL, 0); if (new_bufp == NULL) return (-1); old_bufp->flags |= (BUF_MOD | BUF_PIN); new_bufp->flags |= (BUF_MOD | BUF_PIN); ino = (uint16 *)(op = old_bufp->page); np = new_bufp->page; moved = 0; for (n = 1, ndx = 1; n < ino[0]; n += 2) { if (ino[n + 1] < REAL_KEY) { retval = ugly_split(hashp, obucket, old_bufp, new_bufp, (int)copyto, (int)moved); old_bufp->flags &= ~BUF_PIN; new_bufp->flags &= ~BUF_PIN; return (retval); } key.data = (uint8 *)op + ino[n]; /* check here for ino[n] being greater than * off. If it is then the database has * been corrupted. */ if (ino[n] > off) return (DATABASE_CORRUPTED_ERROR); key.size = off - ino[n]; #ifdef DEBUG /* make sure the size is positive */ assert(((int)key.size) > -1); #endif if (__call_hash(hashp, (char *)key.data, key.size) == obucket) { /* Don't switch page */ diff = copyto - off; if (diff) { copyto = ino[n + 1] + diff; memmove(op + copyto, op + ino[n + 1], off - ino[n + 1]); ino[ndx] = copyto + ino[n] - ino[n + 1]; ino[ndx + 1] = copyto; } else copyto = ino[n + 1]; ndx += 2; } else { /* Switch page */ val.data = (uint8 *)op + ino[n + 1]; val.size = ino[n] - ino[n + 1]; /* if the pair doesn't fit something is horribly * wrong. LJM */ tmp_uint16_array = (uint16 *)np; if (!PAIRFITS(tmp_uint16_array, &key, &val)) return (DATABASE_CORRUPTED_ERROR); putpair(np, &key, &val); moved += 2; } off = ino[n + 1]; } /* Now clean up the page */ ino[0] -= moved; FREESPACE(ino) = copyto - sizeof(uint16) * (ino[0] + 3); OFFSET(ino) = copyto; #ifdef DEBUG3 (void)fprintf(stderr, "split %d/%d\n", ((uint16 *)np)[0] / 2, ((uint16 *)op)[0] / 2); #endif /* unpin both pages */ old_bufp->flags &= ~BUF_PIN; new_bufp->flags &= ~BUF_PIN; return (0); }