Exemple #1
0
/*
 * __meta_track_next --
 *	Extend the list of operations we're tracking, as necessary, and
 *	optionally return the next slot.
 */
static int
__meta_track_next(WT_SESSION_IMPL *session, WT_META_TRACK **trkp)
{
	size_t offset, sub_off;

	if (session->meta_track_next == NULL)
		session->meta_track_next = session->meta_track;

	offset = WT_PTRDIFF(session->meta_track_next, session->meta_track);
	sub_off = WT_PTRDIFF(session->meta_track_sub, session->meta_track);
	if (offset == session->meta_track_alloc) {
		WT_RET(__wt_realloc(session, &session->meta_track_alloc,
		    WT_MAX(2 * session->meta_track_alloc,
		    20 * sizeof(WT_META_TRACK)), &session->meta_track));

		/* Maintain positions in the new chunk of memory. */
		session->meta_track_next =
		    (uint8_t *)session->meta_track + offset;
		if (session->meta_track_sub != NULL)
			session->meta_track_sub =
			    (uint8_t *)session->meta_track + sub_off;
	}

	WT_ASSERT(session, session->meta_track_next != NULL);

	if (trkp != NULL) {
		*trkp = session->meta_track_next;
		session->meta_track_next = *trkp + 1;
	}

	return (0);
}
Exemple #2
0
/*
 * __wt_raw_to_esc_hex --
 *	Convert a chunk of data to a nul-terminated printable string using
 * escaped hex, as necessary.
 */
int
__wt_raw_to_esc_hex(
    WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to)
{
	size_t i;
	const uint8_t *p;
	u_char *t;

	/*
	 * In the worst case, every character takes up 3 spaces, plus a
	 * trailing nul byte.
	 */
	WT_RET(__wt_buf_init(session, to, size * 3 + 1));

	for (p = from, t = to->mem, i = size; i > 0; --i, ++p)
		if (__wt_isprint((u_char)*p)) {
			if (*p == '\\')
				*t++ = '\\';
			*t++ = *p;
		} else {
			*t++ = '\\';
			*t++ = __wt_hex((*p & 0xf0) >> 4);
			*t++ = __wt_hex(*p & 0x0f);
		}
	*t++ = '\0';
	to->size = WT_PTRDIFF(t, to->mem);
	return (0);
}
Exemple #3
0
/*
 * __txn_log_recover --
 *	Roll the log forward to recover committed changes.
 */
static int
__txn_log_recover(WT_SESSION_IMPL *session,
    WT_ITEM *logrec, WT_LSN *lsnp, WT_LSN *next_lsnp,
    void *cookie, int firstrecord)
{
	WT_RECOVERY *r;
	const uint8_t *end, *p;
	uint64_t txnid;
	uint32_t rectype;

	WT_UNUSED(next_lsnp);
	r = cookie;
	p = WT_LOG_SKIP_HEADER(logrec->data);
	end = (const uint8_t *)logrec->data + logrec->size;
	WT_UNUSED(firstrecord);

	/* First, peek at the log record type. */
	WT_RET(__wt_logrec_read(session, &p, end, &rectype));

	switch (rectype) {
	case WT_LOGREC_CHECKPOINT:
		if (r->metadata_only)
			WT_RET(__wt_txn_checkpoint_logread(
			    session, &p, end, &r->ckpt_lsn));
		break;

	case WT_LOGREC_COMMIT:
		WT_RET(__wt_vunpack_uint(&p, WT_PTRDIFF(end, p), &txnid));
		WT_UNUSED(txnid);
		WT_RET(__txn_commit_apply(r, lsnp, &p, end));
		break;
	}

	return (0);
}
Exemple #4
0
/*将二级制串转化成16进制串,每个字节描述用"\"隔开*/
int __wt_raw_to_esc_hex(WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to)
{
	size_t i;
	const uint8_t* p;
	u_char*	t;

	WT_RET(__wt_buf_init(session, to, size * 3 + 1));

	for(p = from, t = to->mem, i = size; i > 0; --i, ++p){
		if (isprint((int)*p)) {
			if (*p == '\\')
				*t++ = '\\';
			*t++ = *p;
		} 
		else {
			*t++ = '\\';
			*t++ = hex[(*p & 0xf0) >> 4];
			*t++ = hex[*p & 0x0f];
		}
	}

	*t++ = '\0';
	to->size = WT_PTRDIFF(t, to->mem);
	return 0;
}
Exemple #5
0
/*
 * __wt_debug_offset --
 *	Read and dump a disk page in debugging mode, using a file
 * offset/size/checksum triplet.
 */
int
__wt_debug_offset(WT_SESSION_IMPL *session,
     wt_off_t offset, uint32_t size, uint32_t cksum, const char *ofile)
{
	WT_DECL_ITEM(buf);
	WT_DECL_RET;
	uint8_t addr[WT_BTREE_MAX_ADDR_COOKIE], *endp;

	WT_ASSERT(session, S2BT_SAFE(session) != NULL);

	/*
	 * This routine depends on the default block manager's view of files,
	 * where an address consists of a file offset, length, and checksum.
	 * This is for debugging only: other block managers might not see a
	 * file or address the same way, that's why there's no block manager
	 * method.
	 *
	 * Convert the triplet into an address structure.
	 */
	endp = addr;
	WT_RET(__wt_block_addr_to_buffer(
	    S2BT(session)->bm->block, &endp, offset, size, cksum));

	/*
	 * Read the address through the btree I/O functions (so the block is
	 * decompressed as necessary).
	 */
	WT_RET(__wt_scr_alloc(session, 0, &buf));
	WT_ERR(__wt_bt_read(session, buf, addr, WT_PTRDIFF(endp, addr)));
	ret = __wt_debug_disk(session, buf->mem, ofile);

err:	__wt_scr_free(session, &buf);
	return (ret);
}
Exemple #6
0
/*
 * __wt_struct_unpack_size --
 *	Determine the packed size of a buffer matching the format.
 */
int
__wt_struct_unpack_size(WT_SESSION_IMPL *session,
    const void *buffer, size_t size, const char *fmt, size_t *resultp)
{
	WT_DECL_PACK_VALUE(pv);
	WT_DECL_RET;
	WT_PACK pack;
	const uint8_t *p, *end;

	p = buffer;
	end = p + size;

	WT_RET(__pack_init(session, &pack, fmt));
	while ((ret = __pack_next(&pack, &pv)) == 0)
		WT_RET(__unpack_read(session, &pv, &p, (size_t)(end - p)));

	/* Be paranoid - __pack_write should never overflow. */
	WT_ASSERT(session, p <= end);

	if (ret != WT_NOTFOUND)
		return (ret);

	*resultp = WT_PTRDIFF(p, buffer);
	return (0);
}
Exemple #7
0
int
__wt_logop_read(WT_SESSION_IMPL *session,
    const uint8_t **pp, const uint8_t *end,
    uint32_t *optypep, uint32_t *opsizep)
{
	return (__wt_struct_unpack(
	    session, *pp, WT_PTRDIFF(end, *pp), "II", optypep, opsizep));
}
Exemple #8
0
/*
 * __wt_ovfl_txnc_add --
 *	Add a new entry to the page's list of transaction-cached overflow
 * records.
 */
int
__wt_ovfl_txnc_add(WT_SESSION_IMPL *session, WT_PAGE *page,
    const uint8_t *addr, size_t addr_size,
    const void *value, size_t value_size)
{
	WT_OVFL_TXNC **head, **stack[WT_SKIP_MAXDEPTH], *txnc;
	size_t size;
	u_int i, skipdepth;
	uint8_t *p;

	if (page->modify->ovfl_track == NULL)
		WT_RET(__ovfl_track_init(session, page));

	head = page->modify->ovfl_track->ovfl_txnc;

	/* Choose a skiplist depth for this insert. */
	skipdepth = __wt_skip_choose_depth(session);

	/*
	 * Allocate the WT_OVFL_TXNC structure, next pointers for the skip
	 * list, room for the address and value, then copy everything into
	 * place.
	 *
	 * To minimize the WT_OVFL_TXNC structure size, the address offset
	 * and size are single bytes: that's safe because the address follows
	 * the structure (which can't be more than about 100B), and address
	 * cookies are limited to 255B.
	 */
	size = sizeof(WT_OVFL_TXNC) +
	    skipdepth * sizeof(WT_OVFL_TXNC *) + addr_size + value_size;
	WT_RET(__wt_calloc(session, 1, size, &txnc));
	p = (uint8_t *)txnc +
	    sizeof(WT_OVFL_TXNC) + skipdepth * sizeof(WT_OVFL_TXNC *);
	txnc->addr_offset = (uint8_t)WT_PTRDIFF(p, txnc);
	txnc->addr_size = (uint8_t)addr_size;
	memcpy(p, addr, addr_size);
	p += addr_size;
	txnc->value_offset = WT_PTRDIFF32(p, txnc);
	txnc->value_size = WT_STORE_SIZE(value_size);
	memcpy(p, value, value_size);
	txnc->current = __wt_txn_new_id(session);

	__wt_cache_page_inmem_incr(
	    session, page, WT_OVFL_SIZE(txnc, WT_OVFL_TXNC));

	/* Insert the new entry into the skiplist. */
	__ovfl_txnc_skip_search_stack(head, stack, addr, addr_size);
	for (i = 0; i < skipdepth; ++i) {
		txnc->next[i] = *stack[i];
		*stack[i] = txnc;
	}

	if (WT_VERBOSE_ISSET(session, WT_VERB_OVERFLOW))
		WT_RET(__ovfl_txnc_verbose(session, page, txnc, "add"));

	return (0);
}
Exemple #9
0
/*
 * __wt_buf_grow --
 *	Grow a buffer that's currently in-use.
 */
int
__wt_buf_grow(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size)
{
	size_t offset;
	int set_data;

	WT_ASSERT(session, size <= UINT32_MAX);

	/* Clear buffers previously used for mapped returns. */
	if (F_ISSET(buf, WT_ITEM_MAPPED))
		__wt_buf_clear(buf);

	if (size > buf->memsize) {
		/*
		 * Grow the buffer's memory: if the data reference is not set
		 * or references the buffer's memory, maintain it.
		 */
		WT_ASSERT(session, buf->mem == NULL || buf->memsize > 0);
		if (buf->data == NULL) {
			offset = 0;
			set_data = 1;
		} else if (buf->data >= buf->mem &&
		    WT_PTRDIFF(buf->data, buf->mem) < buf->memsize) {
			offset = WT_PTRDIFF(buf->data, buf->mem);
			set_data = 1;
		} else {
			offset = 0;
			set_data = 0;
		}

		if (F_ISSET(buf, WT_ITEM_ALIGNED))
			WT_RET(__wt_realloc_aligned(
			    session, &buf->memsize, size, &buf->mem));
		else
			WT_RET(__wt_realloc(
			    session, &buf->memsize, size, &buf->mem));

		if (set_data)
			buf->data = (uint8_t *)buf->mem + offset;
	}
	return (0);
}
Exemple #10
0
/*
 * wiredtiger_pack_close --
 *	Close a packing stream.
 */
int
wiredtiger_pack_close(WT_PACK_STREAM *ps, size_t *usedp)
{
	if (usedp != NULL)
		*usedp = WT_PTRDIFF(ps->p, ps->start);

	if (ps != NULL)
		__wt_free(ps->pack.session, ps);

	return (0);
}
Exemple #11
0
int
__wt_logrec_read(WT_SESSION_IMPL *session,
    const uint8_t **pp, const uint8_t *end, uint32_t *rectypep)
{
	uint64_t rectype;

	WT_UNUSED(session);
	WT_RET(__wt_vunpack_uint(pp, WT_PTRDIFF(end, *pp), &rectype));
	*rectypep = (uint32_t)rectype;
	return (0);
}
Exemple #12
0
/*
 * __wt_mmap_preload --
 *	Cause a section of a memory map to be faulted in.
 */
int
__wt_mmap_preload(WT_SESSION_IMPL *session, const void *p, size_t size)
{
#ifdef HAVE_POSIX_MADVISE
	/* Linux requires the address be aligned to a 4KB boundary. */
	WT_BM *bm = S2BT(session)->bm;
	WT_DECL_RET;
	void *blk = (void *)((uintptr_t)p & ~(uintptr_t)(WT_VM_PAGESIZE - 1));
	size += WT_PTRDIFF(p, blk);

	/* XXX proxy for "am I doing a scan?" -- manual read-ahead */
	if (F_ISSET(session, WT_SESSION_NO_CACHE)) {
		/* Read in 2MB blocks every 1MB of data. */
		if (((uintptr_t)((uint8_t *)blk + size) &
		    (uintptr_t)((1<<20) - 1)) < (uintptr_t)blk)
			return (0);
		size = WT_MIN(WT_MAX(20 * size, 2 << 20),
		    WT_PTRDIFF((uint8_t *)bm->map + bm->maplen, blk));
	}

	/*
	 * Manual pages aren't clear on whether alignment is required for the
	 * size, so we will be conservative.
	 */
	size &= ~(size_t)(WT_VM_PAGESIZE - 1);

	if (size > WT_VM_PAGESIZE &&
	    (ret = posix_madvise(blk, size, POSIX_MADV_WILLNEED)) != 0)
		WT_RET_MSG(session, ret, "posix_madvise will need");
#else
	WT_UNUSED(session);
	WT_UNUSED(p);
	WT_UNUSED(size);
#endif

	return (0);
}
Exemple #13
0
/*
 * __wt_schema_get_index --
 *	Find an index by URI.
 */
int
__wt_schema_get_index(WT_SESSION_IMPL *session,
    const char *uri, bool quiet, WT_TABLE **tablep, WT_INDEX **indexp)
{
	WT_DECL_RET;
	WT_INDEX *idx;
	WT_TABLE *table;
	const char *tablename, *tend;
	u_int i;

	*indexp = NULL;

	tablename = uri;
	if (!WT_PREFIX_SKIP(tablename, "index:") ||
	    (tend = strchr(tablename, ':')) == NULL)
		return (__wt_bad_object_type(session, uri));

	WT_RET(__wt_schema_get_table(session,
	    tablename, WT_PTRDIFF(tend, tablename), false, &table));

	/* Try to find the index in the table. */
	for (i = 0; i < table->nindices; i++) {
		idx = table->indices[i];
		if (idx != NULL && strcmp(idx->name, uri) == 0) {
			if (tablep != NULL)
				*tablep = table;
			else
				__wt_schema_release_table(session, table);
			*indexp = idx;
			return (0);
		}
	}

	/* Otherwise, open it. */
	WT_ERR(__wt_schema_open_index(
	    session, table, tend + 1, strlen(tend + 1), indexp));
	if (tablep != NULL)
		*tablep = table;

err:	__wt_schema_release_table(session, table);
	WT_RET(ret);

	if (*indexp != NULL)
		return (0);

	if (quiet)
		WT_RET(ENOENT);
	WT_RET_MSG(session, ENOENT, "%s not found in table", uri);
}
Exemple #14
0
int
__wt_logop_row_truncate_unpack(
    WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end,
    uint32_t *fileidp, WT_ITEM *startp, WT_ITEM *stopp, uint32_t *modep)
{
	const char *fmt = WT_UNCHECKED_STRING(IIIuuI);
	uint32_t optype, size;

	WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt,
	    &optype, &size, fileidp, startp, stopp, modep));
	WT_ASSERT(session, optype == WT_LOGOP_ROW_TRUNCATE);

	*pp += size;
	return (0);
}
Exemple #15
0
int
__wt_logop_row_remove_unpack(
    WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end,
    uint32_t *fileidp, WT_ITEM *keyp)
{
	const char *fmt = WT_UNCHECKED_STRING(IIIu);
	uint32_t optype, size;

	WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt,
	    &optype, &size, fileidp, keyp));
	WT_ASSERT(session, optype == WT_LOGOP_ROW_REMOVE);

	*pp += size;
	return (0);
}
Exemple #16
0
/*将buffer的数据写入到block对应的文件中*/
int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, int data_cksum)
{
	wt_off_t offset;
	uint32_t size, cksum;
	uint8_t *endp;

	WT_RET(__wt_block_write_off(session, block, buf, &offset, &size, &cksum, data_cksum, 0));

	endp = addr;
	/*将block的checksum/长度对齐个数/偏移位置写入addr中*/
	WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, cksum));
	*addr_sizep = WT_PTRDIFF(endp, addr);

	return 0;
}
Exemple #17
0
int
__wt_logop_col_put_unpack(
    WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end,
    uint32_t *fileidp, uint64_t *recnop, WT_ITEM *valuep)
{
	const char *fmt = WT_UNCHECKED_STRING(IIIru);
	uint32_t optype, size;

	WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt,
	    &optype, &size, fileidp, recnop, valuep));
	WT_ASSERT(session, optype == WT_LOGOP_COL_PUT);

	*pp += size;
	return (0);
}
Exemple #18
0
/*将src转换成可见的16进制串*/
static inline void __fill_hex(const uint8_t* src, size_t src_max, uint8_t* dest, size_t dest_max, size_t* lenp)
{
	uint8_t* dest_orig;
	
	dest_orig = dest;
	if(dest_max > 0)
		-- dest_max;
	for(; src_max > 0 && dest_max > 1; src_max -= 1, dest_max -= 2, ++src){
		*dest++ = hex[(*src & 0xf0) >> 4];
		*dest++ = hex[*src & 0x0f];
	}

	*dest++ = '\0';
	if(lenp != NULL)
		*lenp = WT_PTRDIFF(dest, dest_orig);
}
Exemple #19
0
/*
 * __wt_block_write --
 *	Write a buffer into a block, returning the block's address cookie.
 */
int
__wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block,
    WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_cksum)
{
	wt_off_t offset;
	uint32_t size, cksum;
	uint8_t *endp;

	WT_RET(__wt_block_write_off(
	    session, block, buf, &offset, &size, &cksum, data_cksum, false));

	endp = addr;
	WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, cksum));
	*addr_sizep = WT_PTRDIFF(endp, addr);

	return (0);
}
Exemple #20
0
/*
 * __txn_log_recover --
 *	Roll the log forward to recover committed changes.
 */
static int
__txn_log_recover(WT_SESSION_IMPL *session,
    WT_ITEM *logrec, WT_LSN *lsnp, WT_LSN *next_lsnp,
    void *cookie, int firstrecord)
{
	WT_DECL_RET;
	WT_RECOVERY *r;
	uint64_t txnid_unused;
	uint32_t rectype;
	const uint8_t *end, *p;

	r = cookie;
	p = WT_LOG_SKIP_HEADER(logrec->data);
	end = (const uint8_t *)logrec->data + logrec->size;
	WT_UNUSED(firstrecord);

	/* First, peek at the log record type. */
	WT_RET(__wt_logrec_read(session, &p, end, &rectype));

	/*
	 * Record the highest LSN we process during the metadata phase.
	 * If not the metadata phase, then stop at that LSN.
	 */
	if (r->metadata_only)
		r->max_rec_lsn = *next_lsnp;
	else if (__wt_log_cmp(lsnp, &r->max_rec_lsn) >= 0)
		return (0);

	switch (rectype) {
	case WT_LOGREC_CHECKPOINT:
		if (r->metadata_only)
			WT_RET(__wt_txn_checkpoint_logread(
			    session, &p, end, &r->ckpt_lsn));
		break;

	case WT_LOGREC_COMMIT:
		if ((ret = __wt_vunpack_uint(
		    &p, WT_PTRDIFF(end, p), &txnid_unused)) != 0)
			WT_RET_MSG(
			    session, ret, "txn_log_recover: unpack failure");
		WT_RET(__txn_commit_apply(r, lsnp, &p, end));
		break;
	}

	return (0);
}
Exemple #21
0
/*
 * __wt_txn_checkpoint_logread --
 *	Read a log record for a checkpoint operation.
 */
int
__wt_txn_checkpoint_logread(
    WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end,
    WT_LSN *ckpt_lsn)
{
	const char *fmt = WT_UNCHECKED_STRING(IQIU);
	WT_ITEM ckpt_snapshot;
	u_int ckpt_nsnapshot;

	WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt,
	    &ckpt_lsn->file, &ckpt_lsn->offset,
	    &ckpt_nsnapshot, &ckpt_snapshot));
	WT_UNUSED(ckpt_nsnapshot);
	WT_UNUSED(ckpt_snapshot);
	*pp = end;
	return (0);
}
Exemple #22
0
/*
 * __curlog_logrec --
 *	Callback function from log_scan to get a log record.
 */
static int
__curlog_logrec(WT_SESSION_IMPL *session,
    WT_ITEM *logrec, WT_LSN *lsnp, WT_LSN *next_lsnp,
    void *cookie, int firstrecord)
{
	WT_CURSOR_LOG *cl;

	cl = cookie;
	WT_UNUSED(firstrecord);

	/* Set up the LSNs and take a copy of the log record for the cursor. */
	*cl->cur_lsn = *lsnp;
	*cl->next_lsn = *next_lsnp;
	WT_RET(__wt_buf_set(session, cl->logrec, logrec->data, logrec->size));

	/*
	 * Read the log header.  Set up the step pointers to walk the
	 * operations inside the record.  Get the record type.
	 */
	cl->stepp = WT_LOG_SKIP_HEADER(cl->logrec->data);
	cl->stepp_end = (uint8_t *)cl->logrec->data + logrec->size;
	WT_RET(__wt_logrec_read(session, &cl->stepp, cl->stepp_end,
	    &cl->rectype));

	/* A step count of 0 means the entire record. */
	cl->step_count = 0;

	/*
	 * Unpack the txnid so that we can return each
	 * individual operation for this txnid.
	 */
	if (cl->rectype == WT_LOGREC_COMMIT)
		WT_RET(__wt_vunpack_uint(&cl->stepp,
		    WT_PTRDIFF(cl->stepp_end, cl->stepp), &cl->txnid));
	else {
		/*
		 * Step over anything else.
		 * Setting stepp to NULL causes the next()
		 * method to read a new record on the next call.
		 */
		cl->stepp = NULL;
		cl->txnid = 0;
	}
	return (0);
}
Exemple #23
0
/*
 * __wt_mmap_discard --
 *	Discard a chunk of the memory map.
 */
int
__wt_mmap_discard(WT_SESSION_IMPL *session, void *p, size_t size)
{
#ifdef HAVE_POSIX_MADVISE
	/* Linux requires the address be aligned to a 4KB boundary. */
	WT_DECL_RET;
	void *blk = (void *)((uintptr_t)p & ~(uintptr_t)(WT_VM_PAGESIZE - 1));
	size += WT_PTRDIFF(p, blk);

	if ((ret = posix_madvise(blk, size, POSIX_MADV_DONTNEED)) != 0)
		WT_RET_MSG(session, ret, "posix_madvise don't need");
#else
	WT_UNUSED(session);
	WT_UNUSED(p);
	WT_UNUSED(size);
#endif
	return (0);
}
Exemple #24
0
/*
 * __fill_hex --
 *	In-memory conversion of raw bytes to a hexadecimal representation.
 */
static inline void
__fill_hex(const uint8_t *src, size_t src_max,
    uint8_t *dest, size_t dest_max, size_t *lenp)
{
	uint8_t *dest_orig;

	dest_orig = dest;
	if (dest_max > 0)		/* save a byte for nul-termination */
		--dest_max;
	for (; src_max > 0 && dest_max > 1;
	    src_max -= 1, dest_max -= 2, ++src) {
		*dest++ = __wt_hex((*src & 0xf0) >> 4);
		*dest++ = __wt_hex(*src & 0x0f);
	}
	*dest++ = '\0';
	if (lenp != NULL)
		*lenp = WT_PTRDIFF(dest, dest_orig);
}
Exemple #25
0
/*将16进制描述串转换成二进制串,并且存入item中*/
int __wt_nhex_to_raw(WT_SESSION_IMPL *session, const char *from, size_t size, WT_ITEM *to)
{
	const u_char *p;
	u_char *t;

	if (size % 2 != 0)
		return (__hex_fmterr(session));

	WT_RET(__wt_buf_init(session, to, size / 2));

	for (p = (u_char *)from, t = to->mem; size > 0; p += 2, size -= 2, ++t){
		if (__wt_hex2byte(p, t))
			return (__hex_fmterr(session));
	}

	to->size = WT_PTRDIFF(t, to->mem);
	return 0;
}
Exemple #26
0
/*
 * __fstream_getline --
 *	Get a line from a stream.
 *
 * Implementation of the POSIX getline or BSD fgetln functions (finding the
 * function in a portable way is hard, it's simple enough to write it instead).
 *
 * Note: Unlike the standard getline calls, this function doesn't include the
 * trailing newline character in the returned buffer and discards empty lines
 * (so the caller's EOF marker is a returned line length of 0).
 */
static int
__fstream_getline(WT_SESSION_IMPL *session, WT_FSTREAM *fstr, WT_ITEM *buf)
{
	const char *p;
	size_t len;
	char c;

	/*
	 * We always NUL-terminate the returned string (even if it's empty),
	 * make sure there's buffer space for a trailing NUL in all cases.
	 */
	WT_RET(__wt_buf_init(session, buf, 100));

	for (;;) {
		/* Check if we need to refill the buffer. */
		if (WT_PTRDIFF(fstr->buf.data, fstr->buf.mem) >=
		    fstr->buf.size) {
			len = WT_MIN(WT_STREAM_BUFSIZE,
			    (size_t)(fstr->size - fstr->off));
			if (len == 0)
				break; /* EOF */
			WT_RET(__wt_buf_initsize(session, &fstr->buf, len));
			WT_RET(__wt_read(
			    session, fstr->fh, fstr->off, len, fstr->buf.mem));
			fstr->off += (wt_off_t)len;
		}

		c = *(p = fstr->buf.data);
		fstr->buf.data = ++p;

		/* Leave space for a trailing NUL. */
		WT_RET(__wt_buf_extend(session, buf, buf->size + 2));
		if (c == '\n') {
			if (buf->size == 0)
				continue;
			break;
		}
		((char *)buf->mem)[buf->size++] = c;
	}

	((char *)buf->mem)[buf->size] = '\0';

	return (0);
}
Exemple #27
0
/*
 * __wt_txn_checkpoint_logread --
 *	Read a log record for a checkpoint operation.
 */
int
__wt_txn_checkpoint_logread(WT_SESSION_IMPL *session,
    const uint8_t **pp, const uint8_t *end, WT_LSN *ckpt_lsn)
{
	WT_DECL_RET;
	WT_ITEM ckpt_snapshot_unused;
	uint32_t ckpt_file, ckpt_offset;
	u_int ckpt_nsnapshot_unused;
	const char *fmt = WT_UNCHECKED_STRING(IIIu);

	if ((ret = __wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt,
	    &ckpt_file, &ckpt_offset,
	    &ckpt_nsnapshot_unused, &ckpt_snapshot_unused)) != 0)
		WT_RET_MSG(session,
		    ret, "txn_checkpoint_logread: unpack failure");
	WT_SET_LSN(ckpt_lsn, ckpt_file, ckpt_offset);
	*pp = end;
	return (0);
}
Exemple #28
0
/*
 * __wt_struct_repack --
 *	Return the subset of the packed buffer that represents part of
 *	the format.  If the result is not contiguous in the existing
 *	buffer, a buffer is reallocated and filled.
 */
int
__wt_struct_repack(WT_SESSION_IMPL *session, const char *infmt,
    const char *outfmt, const WT_ITEM *inbuf, WT_ITEM *outbuf)
{
	WT_DECL_PACK_VALUE(pvin);
	WT_DECL_PACK_VALUE(pvout);
	WT_DECL_RET;
	WT_PACK packin, packout;
	const uint8_t *before, *end, *p;
	const void *start;

	start = NULL;
	p = inbuf->data;
	end = p + inbuf->size;

	WT_RET(__pack_init(session, &packout, outfmt));
	WT_RET(__pack_init(session, &packin, infmt));

	/* Outfmt should complete before infmt */
	while ((ret = __pack_next(&packout, &pvout)) == 0) {
		if (p >= end)
			WT_RET(EINVAL);
		if (pvout.type == 'x' && pvout.size == 0 && pvout.havesize)
			continue;
		WT_RET(__pack_next(&packin, &pvin));
		before = p;
		WT_RET(__unpack_read(session, &pvin, &p, (size_t)(end - p)));
		if (pvout.type != pvin.type)
			WT_RET(ENOTSUP);
		if (start == NULL)
			start = before;
	}
	WT_RET_NOTFOUND_OK(ret);

	/* Be paranoid - __pack_write should never overflow. */
	WT_ASSERT(session, p <= end);

	outbuf->data = start;
	outbuf->size = WT_PTRDIFF(p, start);

	return (0);
}
Exemple #29
0
/*带有'\'格式化的16进制串转化成二进制串,并且存入item中*/
int __wt_esc_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to)
{
	const u_char *p;
	u_char *t;

	WT_RET(__wt_buf_init(session, to, strlen(from)));

	for (p = (u_char *)from, t = to->mem; *p != '\0'; ++p, ++t) {
		if ((*t = *p) != '\\')
			continue;
		++p;
		if (p[0] != '\\') {
			if (p[0] == '\0' || p[1] == '\0' || __wt_hex2byte(p, t))
				return (__hex_fmterr(session));
			++p;
		}
	}
	to->size = WT_PTRDIFF(t, to->mem);
	return (0);
}
Exemple #30
0
/*
 * __wt_schema_get_colgroup --
 *	Find a column group by URI.
 */
int
__wt_schema_get_colgroup(WT_SESSION_IMPL *session,
    const char *uri, bool quiet, WT_TABLE **tablep, WT_COLGROUP **colgroupp)
{
	WT_COLGROUP *colgroup;
	WT_TABLE *table;
	const char *tablename, *tend;
	u_int i;

	*colgroupp = NULL;

	tablename = uri;
	if (!WT_PREFIX_SKIP(tablename, "colgroup:"))
		return (__wt_bad_object_type(session, uri));

	if ((tend = strchr(tablename, ':')) == NULL)
		tend = tablename + strlen(tablename);

	WT_RET(__wt_schema_get_table(session,
	    tablename, WT_PTRDIFF(tend, tablename), false, &table));

	for (i = 0; i < WT_COLGROUPS(table); i++) {
		colgroup = table->cgroups[i];
		if (strcmp(colgroup->name, uri) == 0) {
			*colgroupp = colgroup;
			if (tablep != NULL)
				*tablep = table;
			else
				__wt_schema_release_table(session, table);
			return (0);
		}
	}

	__wt_schema_release_table(session, table);
	if (quiet)
		WT_RET(ENOENT);
	WT_RET_MSG(session, ENOENT, "%s not found in table", uri);
}