예제 #1
0
static couchstore_error_t by_id_read_docinfo(DocInfo **pInfo, sized_buf *k, sized_buf *v)
{
    const raw_id_index_value *raw = (const raw_id_index_value*)v->buf;
    ssize_t revMetaSize = v->size - sizeof(*raw);
    if (revMetaSize < 0) {
        return COUCHSTORE_ERROR_CORRUPT;
    }

    uint32_t datasize, deleted;
    uint8_t content_meta;
    uint64_t bp, seq, revnum;

    seq = decode_raw48(raw->db_seq);
    datasize = decode_raw32(raw->size);
    bp = decode_raw48(raw->bp);
    deleted = (bp & BP_DELETED_FLAG) != 0;
    bp &= ~BP_DELETED_FLAG;
    content_meta = decode_raw08(raw->content_meta);
    revnum = decode_raw48(raw->rev_seq);

    sized_buf rev_meta = {v->buf + sizeof(*raw), revMetaSize};
    DocInfo* docInfo = couchstore_alloc_docinfo(k, &rev_meta);
    if (!docInfo) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    docInfo->db_seq = seq;
    docInfo->rev_seq = revnum;
    docInfo->deleted = deleted;
    docInfo->bp = bp;
    docInfo->size = datasize;
    docInfo->content_meta = content_meta;
    *pInfo = docInfo;
    return COUCHSTORE_SUCCESS;
}
예제 #2
0
static couchstore_error_t by_seq_read_docinfo(DocInfo **pInfo, sized_buf *k, sized_buf *v)
{
    const raw_seq_index_value *raw = (const raw_seq_index_value*)v->buf;
    ssize_t extraSize = v->size - sizeof(*raw);
    if (extraSize < 0) {
        return COUCHSTORE_ERROR_CORRUPT;
    }

    uint32_t idsize, datasize;
    decode_kv_length(&raw->sizes, &idsize, &datasize);
    uint64_t bp = decode_raw48(raw->bp);
    int deleted = (bp & BP_DELETED_FLAG) != 0;
    bp &= ~BP_DELETED_FLAG;
    uint8_t content_meta = decode_raw08(raw->content_meta);
    uint64_t rev_seq = decode_raw48(raw->rev_seq);
    uint64_t db_seq = decode_sequence_key(k);

    sized_buf id = {v->buf + sizeof(*raw), idsize};
    sized_buf rev_meta = {id.buf + idsize, extraSize - id.size};
    DocInfo* docInfo = couchstore_alloc_docinfo(&id, &rev_meta);
    if (!docInfo) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    docInfo->db_seq = db_seq;
    docInfo->rev_seq = rev_seq;
    docInfo->deleted = deleted;
    docInfo->bp = bp;
    docInfo->size = datasize;
    docInfo->content_meta = content_meta;
    *pInfo = docInfo;
    return COUCHSTORE_SUCCESS;
}
예제 #3
0
// Attempts to initialize the database from a header at the given file position
static couchstore_error_t find_header_at_pos(Db *db, cs_off_t pos)
{
    int errcode = COUCHSTORE_SUCCESS;
    raw_file_header *header_buf = NULL;
    uint8_t buf[2];
    ssize_t readsize = db->file.ops->pread(db->file.handle, buf, 2, pos);
    error_unless(readsize == 2, COUCHSTORE_ERROR_READ);
    if (buf[0] == 0) {
        return COUCHSTORE_ERROR_NO_HEADER;
    } else if (buf[0] != 1) {
        return COUCHSTORE_ERROR_CORRUPT;
    }

    int header_len = pread_header(&db->file, pos, (char**)&header_buf);
    if (header_len < 0) {
        error_pass(header_len);
    }

    db->header.position = pos;
    db->header.disk_version = decode_raw08(header_buf->version);
    error_unless(db->header.disk_version == COUCH_DISK_VERSION,
                 COUCHSTORE_ERROR_HEADER_VERSION);
    db->header.update_seq = decode_raw48(header_buf->update_seq);
    db->header.purge_seq = decode_raw48(header_buf->purge_seq);
    db->header.purge_ptr = decode_raw48(header_buf->purge_ptr);
    error_unless(db->header.purge_ptr <= db->header.position, COUCHSTORE_ERROR_CORRUPT);
    int seqrootsize = decode_raw16(header_buf->seqrootsize);
    int idrootsize = decode_raw16(header_buf->idrootsize);
    int localrootsize = decode_raw16(header_buf->localrootsize);
    error_unless(header_len == HEADER_BASE_SIZE + seqrootsize + idrootsize + localrootsize,
                 COUCHSTORE_ERROR_CORRUPT);

    char *root_data = (char*) (header_buf + 1);  // i.e. just past *header_buf
    error_pass(read_db_root(db, &db->header.by_seq_root, root_data, seqrootsize));
    root_data += seqrootsize;
    error_pass(read_db_root(db, &db->header.by_id_root, root_data, idrootsize));
    root_data += idrootsize;
    error_pass(read_db_root(db, &db->header.local_docs_root, root_data, localrootsize));

cleanup:
    free(header_buf);
    return errcode;
}
예제 #4
0
static int by_id_read_docinfo(DocInfo **pInfo, sized_buf *k, sized_buf *v)
{
    const raw_id_index_value *raw = (const raw_id_index_value*)v->buf;
    ssize_t revMetaSize = v->size - sizeof(*raw);
    if (revMetaSize < 0) {
        return COUCHSTORE_ERROR_CORRUPT;
    }

    uint32_t datasize, deleted;
    uint8_t content_meta;
    uint64_t bp, seq, revnum;

    seq = decode_raw48(raw->db_seq);
    datasize = decode_raw32(raw->size);
    bp = decode_raw48(raw->bp);
    deleted = (bp & BP_DELETED_FLAG) != 0;
    bp &= ~BP_DELETED_FLAG;
    content_meta = decode_raw08(raw->content_meta);
    revnum = decode_raw48(raw->rev_seq);

    DocInfo* docInfo = malloc(sizeof(DocInfo) + revMetaSize + k->size);
    if (!docInfo) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }
    char *rbuf = (char *) docInfo;
    memcpy(rbuf + sizeof(DocInfo), v->buf + sizeof(*raw), revMetaSize);
    *pInfo = docInfo;
    docInfo->db_seq = seq;
    docInfo->rev_seq = revnum;
    docInfo->deleted = deleted;
    docInfo->bp = bp;
    docInfo->size = datasize;
    docInfo->content_meta = content_meta;
    docInfo->rev_meta.buf = rbuf + sizeof(DocInfo);
    docInfo->rev_meta.size = revMetaSize;
    docInfo->id.buf = docInfo->rev_meta.buf + docInfo->rev_meta.size;
    docInfo->id.size = k->size;
    memcpy(docInfo->id.buf, k->buf, k->size);
    return 0;
}
예제 #5
0
static int by_seq_read_docinfo(DocInfo **pInfo, sized_buf *k, sized_buf *v)
{
    const raw_seq_index_value *raw = (const raw_seq_index_value*)v->buf;
    ssize_t extraSize = v->size - sizeof(*raw);
    if (extraSize < 0) {
        return COUCHSTORE_ERROR_CORRUPT;
    }

    uint32_t idsize, datasize;
    decode_kv_length(&raw->sizes, &idsize, &datasize);
    uint64_t bp = decode_raw48(raw->bp);
    int deleted = (bp & BP_DELETED_FLAG) != 0;
    bp &= ~BP_DELETED_FLAG;
    uint8_t content_meta = decode_raw08(raw->content_meta);
    uint64_t rev_seq = decode_raw48(raw->rev_seq);
    uint64_t db_seq = decode_sequence_key(k);

    DocInfo* docInfo = malloc(sizeof(DocInfo) + extraSize);
    if (!docInfo) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }
    char *rbuf = (char *) docInfo;
    memcpy(rbuf + sizeof(DocInfo), v->buf + sizeof(*raw), extraSize);
    *pInfo = docInfo;
    docInfo->db_seq = db_seq;
    docInfo->rev_seq = rev_seq;
    docInfo->deleted = deleted;
    docInfo->bp = bp;
    docInfo->size = datasize;
    docInfo->content_meta = content_meta;
    docInfo->id.buf = rbuf + sizeof(DocInfo);
    docInfo->id.size = idsize;
    docInfo->rev_meta.buf = rbuf + sizeof(DocInfo) + idsize;
    docInfo->rev_meta.size = extraSize - idsize;
    return 0;
}
예제 #6
0
파일: testapp.c 프로젝트: acm7/couchstore
static void test_raw_08(uint8_t value)
{
    raw_08 raw;
    raw = encode_raw08(value);
    assert(decode_raw08(raw) == value);
}