int view_spatial_filter(const sized_buf *k, const sized_buf *v, const bitmap_t *bm) { uint16_t partition = 0; (void) k; partition = decode_raw16(*((raw_16 *) v->buf)); return is_bit_set(bm, partition); }
// 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; }
int spatial_key_cmp(const sized_buf *key1, const sized_buf *key2, const void *user_ctx) { scale_factor_t *sf = ((view_spatial_builder_ctx_t *) user_ctx)->scale_factor; uint16_t mbb1_num = decode_raw16(*((raw_16 *) key1->buf)); uint16_t mbb2_num = decode_raw16(*((raw_16 *) key2->buf)); sized_mbb_t mbbs[2]; double *mbbs_center[2]; uint32_t *mbbs_scaled[2]; unsigned char *mbbs_zcode[2]; int res; mbbs[0].num = mbb1_num; mbbs[0].mbb = (double *)(key1->buf + sizeof(uint16_t)); mbbs_center[0] = spatial_center(&mbbs[0]); mbbs_scaled[0] = spatial_scale_point(mbbs_center[0], sf); mbbs_zcode[0] = interleave_uint32s(mbbs_scaled[0], sf->dim); mbbs[1].num = mbb2_num; mbbs[1].mbb = (double *)(key2->buf + sizeof(uint16_t)); mbbs_center[1] = spatial_center(&mbbs[1]); mbbs_scaled[1] = spatial_scale_point(mbbs_center[1], sf); mbbs_zcode[1] = interleave_uint32s(mbbs_scaled[1], sf->dim); res = memcmp(mbbs_zcode[0], mbbs_zcode[1], sf->dim * BYTE_PER_COORD); free(mbbs_center[0]); free(mbbs_scaled[0]); free(mbbs_zcode[0]); free(mbbs_center[1]); free(mbbs_scaled[1]); free(mbbs_zcode[1]); return res; }
static node_pointer *read_pointer(arena* a, sized_buf *key, char *buf) { //Parse KP pair into a node_pointer {K, {ptr, reduce_value, subtreesize}} node_pointer *p = (node_pointer *) arena_alloc(a, sizeof(node_pointer)); if (!p) { return NULL; } const raw_node_pointer *raw = (const raw_node_pointer*)buf; p->pointer = decode_raw48(raw->pointer); p->subtreesize = decode_raw48(raw->subtreesize); p->reduce_value.size = decode_raw16(raw->reduce_value_size); p->reduce_value.buf = buf + sizeof(*raw); p->key = *key; return p; }
STATIC couchstore_error_t decode_spatial_key(const char *key, sized_mbb_t *mbb) { mbb->num = decode_raw16(*((raw_16 *) key)); mbb->mbb = (double *)(key + 2); return COUCHSTORE_SUCCESS; }
static void test_raw_16(uint16_t value) { raw_16 raw; raw = encode_raw16(value); assert(decode_raw16(raw) == value); }
static couchstore_error_t btree_lookup_inner(couchfile_lookup_request *rq, uint64_t diskpos, int current, int end) { int bufpos = 1, nodebuflen = 0; if (current == end) { return 0; } couchstore_error_t errcode = COUCHSTORE_SUCCESS; char *nodebuf = NULL; nodebuflen = pread_compressed(rq->file, diskpos, &nodebuf); error_unless(nodebuflen >= 0, nodebuflen); // if negative, it's an error code if (nodebuf[0] == 0) { //KP Node while (bufpos < nodebuflen && current < end) { sized_buf cmp_key, val_buf; bufpos += read_kv(nodebuf + bufpos, &cmp_key, &val_buf); if (rq->cmp.compare(&cmp_key, rq->keys[current]) >= 0) { if (rq->fold) { rq->in_fold = 1; } uint64_t pointer = 0; int last_item = current; //Descend into the pointed to node. //with all keys < item key. do { last_item++; } while (last_item < end && rq->cmp.compare(&cmp_key, rq->keys[last_item]) >= 0); const raw_node_pointer *raw = (const raw_node_pointer*)val_buf.buf; if(rq->node_callback) { uint64_t subtreeSize = decode_raw48(raw->subtreesize); sized_buf reduce_value = {val_buf.buf + sizeof(raw_node_pointer), decode_raw16(raw->reduce_value_size)}; error_pass(rq->node_callback(rq, subtreeSize, &reduce_value)); } pointer = decode_raw48(raw->pointer); error_pass(btree_lookup_inner(rq, pointer, current, last_item)); if (!rq->in_fold) { current = last_item; } if(rq->node_callback) { error_pass(rq->node_callback(rq, 0, NULL)); } } } } else if (nodebuf[0] == 1) { //KV Node while (bufpos < nodebuflen && current < end) { sized_buf cmp_key, val_buf; bufpos += read_kv(nodebuf + bufpos, &cmp_key, &val_buf); int cmp_val = rq->cmp.compare(&cmp_key, rq->keys[current]); if (cmp_val >= 0 && rq->fold && !rq->in_fold) { rq->in_fold = 1; } else if (rq->in_fold && (current + 1) < end && (rq->cmp.compare(&cmp_key, rq->keys[current + 1])) > 0) { //We've hit a key past the end of our range. rq->in_fold = 0; rq->fold = 0; current = end; } if (cmp_val == 0 || (cmp_val > 0 && rq->in_fold)) { //Found error_pass(rq->fetch_callback(rq, &cmp_key, &val_buf)); if (!rq->in_fold) { current++; } } } } //Any remaining items are not found. while (current < end && !rq->fold) { error_pass(rq->fetch_callback(rq, rq->keys[current], NULL)); current++; } cleanup: free(nodebuf); return errcode; }