示例#1
0
static ham_status_t
_remote_cursor_move(ham_cursor_t *cursor, ham_key_t *key, 
                ham_record_t *record, ham_u32_t flags)
{
    ham_status_t st;
    ham_db_t *db=cursor_get_db(cursor);
    ham_env_t *env=db_get_env(db);
    proto_wrapper_t *request, *reply;
    
    request=proto_init_cursor_move_request(cursor_get_remote_handle(cursor), 
                        key, record, flags);

    st=_perform_request(env, env_get_curl(env), request, &reply);
    proto_delete(request);
    if (st) {
        if (reply)
            proto_delete(reply);
        return (st);
    }

    ham_assert(reply!=0, (""));
    ham_assert(proto_has_cursor_move_reply(reply)!=0, (""));

    st=proto_cursor_move_reply_get_status(reply);
    if (st) 
        goto bail;

    /* modify key/record, but make sure that USER_ALLOC is respected! */
    if (proto_cursor_move_reply_has_key(reply)) {
        ham_assert(key, (""));
        key->_flags=proto_cursor_move_reply_get_key_intflags(reply);
        key->size=proto_cursor_move_reply_get_key_size(reply);
        if (!(key->flags&HAM_KEY_USER_ALLOC)) {
            st=db_resize_key_allocdata(db, key->size);
            if (st)
                goto bail;
            key->data=db_get_key_allocdata(db);
        }
        memcpy(key->data, proto_cursor_move_reply_get_key_data(reply),
                key->size);
    }

    /* same for the record */
    if (proto_cursor_move_reply_has_record(reply)) {
        ham_assert(record, (""));
        record->size=proto_cursor_move_reply_get_record_size(reply);
        if (!(record->flags&HAM_RECORD_USER_ALLOC)) {
            st=db_resize_record_allocdata(db, record->size);
            if (st)
                goto bail;
            record->data=db_get_record_allocdata(db);
        }
        memcpy(record->data, proto_cursor_move_reply_get_record_data(reply),
                record->size);
    }

bail:
    proto_delete(reply);
    return (st);
}
示例#2
0
static ham_status_t
_remote_fun_find(ham_db_t *db, ham_txn_t *txn, ham_key_t *key,
            ham_record_t *record, ham_u32_t flags)
{
    ham_status_t st;
    ham_env_t *env=db_get_env(db);
    proto_wrapper_t *request, *reply;

    request=proto_init_db_find_request(db_get_remote_handle(db), 
                        txn ? txn_get_remote_handle(txn) : 0, 
                        key, record, flags);

    st=_perform_request(env, env_get_curl(env), request, &reply);
    proto_delete(request);
    if (st) {
        if (reply)
            proto_delete(reply);
        return (st);
    }

    ham_assert(reply!=0, (""));
    ham_assert(proto_has_db_find_reply(reply)!=0, (""));

    st=proto_db_find_reply_get_status(reply);
    if (st==0) {
        /* approx. matching: need to copy the _flags and the key data! */
        if (proto_db_find_reply_has_key(reply)) {
            ham_assert(key, (""));
            key->_flags=proto_db_find_reply_get_key_intflags(reply);
            key->size=proto_db_find_reply_get_key_size(reply);
            if (!(key->flags&HAM_KEY_USER_ALLOC)) {
                st=db_resize_key_allocdata(db, key->size);
                if (st)
                    goto bail;
                key->data=db_get_key_allocdata(db);
            }
            memcpy(key->data, proto_db_find_reply_get_key_data(reply),
                    key->size);
        }
        if (proto_db_find_reply_has_record(reply)) {
            record->size=proto_db_find_reply_get_record_size(reply);
            if (!(record->flags&HAM_RECORD_USER_ALLOC)) {
                st=db_resize_record_allocdata(db, record->size);
                if (st)
                    goto bail;
                record->data=db_get_record_allocdata(db);
            }
            memcpy(record->data, proto_db_find_reply_get_record_data(reply),
                    record->size);
        }
    }

bail:
    proto_delete(reply);

    return (st);
}
示例#3
0
static ham_status_t
_remote_cursor_find(ham_cursor_t *cursor, ham_key_t *key, 
                ham_record_t *record, ham_u32_t flags)
{
    ham_status_t st;
    ham_db_t *db=cursor_get_db(cursor);
    ham_env_t *env=db_get_env(db);
    proto_wrapper_t *request, *reply;

    request=proto_init_cursor_find_request(cursor_get_remote_handle(cursor), 
                        key, record, flags);
    
    st=_perform_request(env, env_get_curl(env), request, &reply);
    proto_delete(request);
    if (st) {
        if (reply)
            proto_delete(reply);
        return (st);
    }

    ham_assert(reply!=0, (""));
    ham_assert(proto_has_cursor_find_reply(reply)!=0, (""));

    st=proto_cursor_find_reply_get_status(reply);
    if (st) 
        goto bail;

    /* approx. matching: need to copy the _flags! */
    if (proto_cursor_find_reply_has_key(reply)) {
        key->_flags=proto_cursor_find_reply_get_key_intflags(reply);
    }
    if (proto_cursor_find_reply_has_record(reply)) {
        ham_assert(record, (""));
        record->size=proto_cursor_find_reply_get_record_size(reply);
        if (!(record->flags&HAM_RECORD_USER_ALLOC)) {
            st=db_resize_record_allocdata(db, record->size);
            if (st)
                goto bail;
            record->data=db_get_record_allocdata(db);
        }
        memcpy(record->data, proto_cursor_find_reply_get_record_data(reply),
                record->size);
    }

bail:
    proto_delete(reply);
    return (st);
}
示例#4
0
文件: blob.c 项目: bawerd/hamsterdb
ham_status_t
blob_read(ham_db_t *db, ham_offset_t blobid, 
        ham_record_t *record, ham_u32_t flags)
{
    ham_status_t st;
    ham_page_t *page;
    blob_t hdr;
    ham_size_t blobsize=0;

    /*
     * in-memory-database: the blobid is actually a pointer to the memory
     * buffer, in which the blob is stored
     */
    if (env_get_rt_flags(db_get_env(db))&HAM_IN_MEMORY_DB) {
        blob_t *hdr=(blob_t *)U64_TO_PTR(blobid);
        ham_u8_t *data=(ham_u8_t *)(U64_TO_PTR(blobid))+sizeof(blob_t);

        /* when the database is closing, the header is already deleted */
        if (!hdr) {
            record->size = 0;
            return (0);
        }

        blobsize = (ham_size_t)blob_get_size(hdr);

        if (flags&HAM_PARTIAL) {
            if (record->partial_offset>blobsize) {
                ham_trace(("partial offset is greater than the total "
                            "record size"));
                return (HAM_INV_PARAMETER);
            }
            if (record->partial_offset+record->partial_size>blobsize)
                blobsize=blobsize-record->partial_offset;
            else
                blobsize=record->partial_size;
        }

        if (!blobsize) {
            /* empty blob? */
            record->data = 0;
            record->size = 0;
        }
        else {
            ham_u8_t *d=data;
            if (flags&HAM_PARTIAL)
                d+=record->partial_offset;

            if ((flags&HAM_DIRECT_ACCESS) 
                    && !(record->flags&HAM_RECORD_USER_ALLOC)) {
                record->size=blobsize;
                record->data=d;
            }
            else {
                /* resize buffer, if necessary */
                if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
                    st=db_resize_record_allocdata(db, blobsize);
                    if (st)
                        return (st);
                    record->data = db_get_record_allocdata(db);
                }
                /* and copy the data */
                memcpy(record->data, d, blobsize);
                record->size = blobsize;
            }
        }

        return (0);
    }

    ham_assert(blobid%DB_CHUNKSIZE==0, ("blobid is %llu", blobid));

    /*
     * first step: read the blob header 
     */
    st=__read_chunk(db_get_env(db), 0, &page, blobid, 
                    (ham_u8_t *)&hdr, sizeof(hdr));
    if (st)
        return (st);

    ham_assert(blob_get_alloc_size(&hdr)%DB_CHUNKSIZE==0, (0));

    /*
     * sanity check
     */
    if (blob_get_self(&hdr)!=blobid)
        return (HAM_BLOB_NOT_FOUND);

    blobsize = (ham_size_t)blob_get_size(&hdr);

    if (flags&HAM_PARTIAL) {
        if (record->partial_offset>blobsize) {
            ham_trace(("partial offset+size is greater than the total "
                        "record size"));
            return (HAM_INV_PARAMETER);
        }
        if (record->partial_offset+record->partial_size>blobsize)
            blobsize=blobsize-record->partial_offset;
        else
            blobsize=record->partial_size;
    }

    /* 
     * empty blob? 
     */
    if (!blobsize) {
        record->data = 0;
        record->size = 0;
        return (0);
    }

    /*
     * second step: resize the blob buffer
     */
    if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
        st=db_resize_record_allocdata(db, blobsize);
        if (st)
            return (st);
        record->data = db_get_record_allocdata(db);
    }

    /*
     * third step: read the blob data
     */
    st=__read_chunk(db_get_env(db), page, 0, 
                    blobid+sizeof(blob_t)+(flags&HAM_PARTIAL 
                            ? record->partial_offset 
                            : 0),
                    record->data, blobsize);
    if (st)
        return (st);

    record->size = blobsize;

    return (0);
}