*** btree/bt_put.c.orig Sun Dec 6 11:09:14 1998 --- btree/bt_put.c Tue Mar 9 17:02:52 1999 *************** *** 64,70 **** static int __bam_fixed __P((DBC *, DBT *)); static int __bam_ndup __P((DBC *, PAGE *, u_int32_t)); static int __bam_ovput __P((DBC *, PAGE *, u_int32_t, DBT *)); ! static int __bam_partial __P((DBC *, DBT *, PAGE *, u_int32_t, u_int32_t)); static u_int32_t __bam_partsize __P((DBT *, PAGE *, u_int32_t)); /* --- 64,71 ---- static int __bam_fixed __P((DBC *, DBT *)); static int __bam_ndup __P((DBC *, PAGE *, u_int32_t)); static int __bam_ovput __P((DBC *, PAGE *, u_int32_t, DBT *)); ! static int __bam_partial __P((DBC *, ! DBT *, PAGE *, u_int32_t, u_int32_t, u_int32_t)); static u_int32_t __bam_partsize __P((DBT *, PAGE *, u_int32_t)); /* *************** *** 206,212 **** /* Handle partial puts: build the real record. */ if (F_ISSET(data, DB_DBT_PARTIAL)) { tdbt = *data; ! if ((ret = __bam_partial(dbc, &tdbt, h, indx, data_size)) != 0) return (ret); data = &tdbt; } --- 207,214 ---- /* Handle partial puts: build the real record. */ if (F_ISSET(data, DB_DBT_PARTIAL)) { tdbt = *data; ! if ((ret = __bam_partial(dbc, ! &tdbt, h, indx, data_size, flags)) != 0) return (ret); data = &tdbt; } *************** *** 711,721 **** * Build the real record for a partial put. */ static int ! __bam_partial(dbc, dbt, h, indx, nbytes) DBC *dbc; DBT *dbt; PAGE *h; ! u_int32_t indx, nbytes; { BKEYDATA *bk, tbk; BOVERFLOW *bo; --- 713,723 ---- * Build the real record for a partial put. */ static int ! __bam_partial(dbc, dbt, h, indx, nbytes, flags) DBC *dbc; DBT *dbt; PAGE *h; ! u_int32_t indx, nbytes, flags; { BKEYDATA *bk, tbk; BOVERFLOW *bo; *************** *** 739,744 **** --- 741,764 ---- dbc->rdata.ulen = nbytes; } + /* + * We use nul bytes for any part of the record that isn't specified; + * get it over with. + */ + memset(dbc->rdata.data, 0, nbytes); + + /* + * In the next clauses, we need to do three things: a) set p to point + * to the place at which to copy the user's data, b) set tlen to the + * total length of the record, not including the bytes contributed by + * the user, and c) copy any valid data from an existing record. + */ + if (LF_ISSET(BI_NEWKEY)) { + tlen = dbt->doff; + p = (u_int8_t *)dbc->rdata.data + dbt->doff; + goto ucopy; + } + /* Find the current record. */ if (indx < NUM_ENT(h)) { bk = GET_BKEYDATA(h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0)); *************** *** 748,760 **** B_TSET(bk->type, B_KEYDATA, 0); bk->len = 0; } - - /* - * We use nul bytes for any part of the record that isn't specified, - * get it over with. - */ - memset(dbc->rdata.data, 0, nbytes); - if (B_TYPE(bk->type) == B_OVERFLOW) { /* * In the case of an overflow record, we shift things around --- 768,773 ---- *************** *** 786,795 **** memmove(p + dbt->size, p + dbt->dlen, len); tlen += len; } - - /* Copy in the application provided data. */ - memcpy(p, dbt->data, dbt->size); - tlen += dbt->size; } else { /* Copy in any leading data from the original record. */ memcpy(dbc->rdata.data, --- 799,804 ---- *************** *** 797,806 **** tlen = dbt->doff; p = (u_int8_t *)dbc->rdata.data + dbt->doff; - /* Copy in the application provided data. */ - memcpy(p, dbt->data, dbt->size); - tlen += dbt->size; - /* Copy in any trailing data from the original record. */ len = dbt->doff + dbt->dlen; if (bk->len > len) { --- 806,811 ---- *************** *** 808,813 **** --- 813,825 ---- tlen += bk->len - len; } } + + ucopy: /* + * Copy in the application provided data -- p and tlen must have been + * initialized above. + */ + memcpy(p, dbt->data, dbt->size); + tlen += dbt->size; /* Set the DBT to reference our new record. */ dbc->rdata.size = tlen;