null+****@clear*****
null+****@clear*****
2010年 8月 19日 (木) 18:41:46 JST
Daijiro MORI 2010-08-19 09:41:46 +0000 (Thu, 19 Aug 2010) New Revision: d679b8db09f5069638088125c021efeb1ec2b81c Log: grn_ja supports GRN_OBJ_WITH_BUFFER. Modified files: lib/store.c Modified: lib/store.c (+110 -19) =================================================================== --- lib/store.c 2010-08-19 01:57:08 +0000 (14c0f38) +++ lib/store.c 2010-08-19 09:41:46 +0000 (42964a2) @@ -672,6 +672,28 @@ grn_ja_alloc(grn_ctx *ctx, grn_ja *ja, grn_id id, } } +static grn_rc +set_value(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len, + grn_ja_einfo *einfo) +{ + grn_rc rc = GRN_SUCCESS; + grn_io_win iw; + if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) && + value_len >= ja->header->max_element_size) { + if ((rc = grn_ja_alloc(ctx, ja, id, value_len + sizeof(uint32_t), einfo, &iw))) { + return rc; + } + memcpy(iw.addr, value, value_len); + memset((byte *)iw.addr + value_len, 0, sizeof(uint32_t)); + grn_io_win_unmap2(&iw); + } else { + if ((rc = grn_ja_alloc(ctx, ja, id, value_len, einfo, &iw))) { return rc; } + memcpy(iw.addr, value, value_len); + grn_io_win_unmap2(&iw); + } + return rc; +} + grn_rc grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, void *value, uint32_t value_len, int flags, uint64_t *cas) @@ -687,15 +709,46 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, uint32_t old_len; void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len); if (oldvalue) { - if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) { return rc; } - memcpy(iw.addr, oldvalue, old_len); - memcpy((byte *)iw.addr + old_len, value, value_len); + if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) && + old_len + value_len >= ja->header->max_element_size) { + if (old_len >= ja->header->max_element_size) { + byte *b = oldvalue; + uint32_t el = old_len - sizeof(uint32_t); + uint32_t pos = *((uint32_t *)(b + el)); + GRN_ASSERT(pos < el); + if (el <= pos + value_len) { + uint32_t rest = el - pos; + memcpy(b + pos, value, rest); + memcpy(b, (byte *)value + rest, value_len - rest); + *((uint32_t *)(b + el)) = value_len - rest; + } else { + memcpy(b + pos, value, value_len); + *((uint32_t *)(b + el)) = pos + value_len; + } + } else { + if ((rc = grn_ja_alloc(ctx, ja, id, + value_len + old_len + sizeof(uint32_t), + &einfo, &iw))) { + grn_ja_unref(ctx, &jw); + return rc; + } + memcpy(iw.addr, oldvalue, old_len); + memcpy((byte *)iw.addr + old_len, value, value_len); + memset((byte *)iw.addr + old_len + value_len, 0, sizeof(uint32_t)); + grn_io_win_unmap2(&iw); + } + } else { + if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) { + grn_ja_unref(ctx, &jw); + return rc; + } + memcpy(iw.addr, oldvalue, old_len); + memcpy((byte *)iw.addr + old_len, value, value_len); + grn_io_win_unmap2(&iw); + } grn_ja_unref(ctx, &jw); - grn_io_win_unmap2(&iw); } else { - if ((rc = grn_ja_alloc(ctx, ja, id, value_len, &einfo, &iw))) { return rc; } - memcpy(iw.addr, value, value_len); - grn_io_win_unmap2(&iw); + set_value(ctx, ja, id, value, value_len, &einfo); } } break; @@ -705,15 +758,46 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, uint32_t old_len; void *oldvalue = grn_ja_ref(ctx, ja, id, &jw, &old_len); if (oldvalue) { - if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) { return rc; } - memcpy(iw.addr, value, value_len); - memcpy((byte *)iw.addr + value_len, oldvalue, old_len); + if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) && + old_len + value_len >= ja->header->max_element_size) { + if (old_len >= ja->header->max_element_size) { + byte *b = oldvalue; + uint32_t el = old_len - sizeof(uint32_t); + uint32_t pos = *((uint32_t *)(b + el)); + GRN_ASSERT(pos < el); + if (pos < value_len) { + uint32_t rest = value_len - pos; + memcpy(b, (byte *)value + rest, pos); + memcpy(b + el - rest, value, rest); + *((uint32_t *)(b + el)) = el - rest; + } else { + memcpy(b + pos - value_len, value, value_len); + *((uint32_t *)(b + el)) = pos - value_len; + } + } else { + if ((rc = grn_ja_alloc(ctx, ja, id, + value_len + old_len + sizeof(uint32_t), + &einfo, &iw))) { + grn_ja_unref(ctx, &jw); + return rc; + } + memcpy(iw.addr, value, value_len); + memcpy((byte *)iw.addr + value_len, oldvalue, old_len); + memset((byte *)iw.addr + value_len + old_len, 0, sizeof(uint32_t)); + grn_io_win_unmap2(&iw); + } + } else { + if ((rc = grn_ja_alloc(ctx, ja, id, value_len + old_len, &einfo, &iw))) { + grn_ja_unref(ctx, &jw); + return rc; + } + memcpy(iw.addr, value, value_len); + memcpy((byte *)iw.addr + value_len, oldvalue, old_len); + grn_io_win_unmap2(&iw); + } grn_ja_unref(ctx, &jw); - grn_io_win_unmap2(&iw); } else { - if ((rc = grn_ja_alloc(ctx, ja, id, value_len, &einfo, &iw))) { return rc; } - memcpy(iw.addr, value, value_len); - grn_io_win_unmap2(&iw); + set_value(ctx, ja, id, value, value_len, &einfo); } } break; @@ -751,10 +835,7 @@ grn_ja_put_raw(grn_ctx *ctx, grn_ja *ja, grn_id id, /* fallthru */ case GRN_OBJ_SET : if (value_len) { - if ((rc = grn_ja_alloc(ctx, ja, id, value_len, &einfo, &iw))) { return rc; } - // printf("put id=%d, value_len=%d value=%p ei=%p(%d:%d)\n", id, value_len, buf, &einfo, einfo.pos, einfo.tail[0]); - memcpy(iw.addr, value, value_len); - grn_io_win_unmap2(&iw); + set_value(ctx, ja, id, value, value_len, &einfo); } else { memset(&einfo, 0, sizeof(grn_ja_einfo)); } @@ -991,7 +1072,17 @@ grn_ja_get_value(grn_ctx *ctx, grn_ja *ja, grn_id id, grn_obj *value) } } if ((v = grn_ja_ref(ctx, ja, id, &iw, &len))) { - grn_bulk_write(ctx, value, v, len); + if ((ja->header->flags & GRN_OBJ_WITH_BUFFER) && + len > ja->header->max_element_size) { + byte *b = v; + uint32_t el = len - sizeof(uint32_t); + uint32_t pos = *((uint32_t *)(b + el)); + GRN_ASSERT(pos < el); + grn_bulk_write(ctx, value, b + pos, el - pos); + grn_bulk_write(ctx, value, b, pos); + } else { + grn_bulk_write(ctx, value, v, len); + } grn_ja_unref(ctx, &iw); } exit :