コード例 #1
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
static void
__simple_checks(struct radix_tree_root *tree, unsigned long index, int tag)
{
	unsigned long first = 0;
	int ret;

	item_check_absent(tree, index);
	assert(item_tag_get(tree, index, tag) == 0);

	item_insert(tree, index);
	assert(item_tag_get(tree, index, tag) == 0);
	item_tag_set(tree, index, tag);
	ret = item_tag_get(tree, index, tag);
	assert(ret != 0);
	ret = tag_tagged_items(tree, NULL, first, ~0UL, 10, tag, !tag);
	assert(ret == 1);
	ret = item_tag_get(tree, index, !tag);
	assert(ret != 0);
	ret = item_delete(tree, index);
	assert(ret != 0);
	item_insert(tree, index);
	ret = item_tag_get(tree, index, tag);
	assert(ret == 0);
	ret = item_delete(tree, index);
	assert(ret != 0);
	ret = item_delete(tree, index);
	assert(ret == 0);
}
コード例 #2
0
ファイル: misc.c プロジェクト: nohuhu/TuTTY
int find_existing_processes(void)
{
    struct windowlist *wl = NULL;
    struct process_record *pr = NULL;
    unsigned int i, count;

    wl = (struct windowlist *) malloc(sizeof(struct windowlist));
    memset(wl, 0, sizeof(struct windowlist));

    EnumWindows(CountPuTTYWindows, (LPARAM) &wl->nhandles);
    count = wl->nhandles;

    if (wl->nhandles == 0)
	wl->handles = NULL;
    else {
	wl->handles = (HWND *) malloc(wl->nhandles * sizeof(HWND));
	memset(wl->handles, 0, wl->nhandles * sizeof(HWND));

	EnumWindows(EnumPuTTYWindows, (LPARAM) wl);

	for (i = 0; i < wl->nhandles; i++) {
	    DWORD pid = 0, tid = 0;
	    HANDLE hprocess;

	    tid = GetWindowThreadProcessId(wl->handles[i], &pid);
	    hprocess = OpenProcess(PROCESS_QUERY_INFORMATION | 
				   PROCESS_TERMINATE | 
				   PROCESS_VM_READ |
				   SYNCHRONIZE, FALSE, pid);

	    if (!pid || !tid || !hprocess)
		continue;

	    pr = (struct process_record *) malloc(sizeof(struct process_record));
	    pr->pid = pid;
	    pr->tid = tid;
	    pr->hprocess = hprocess;
	    pr->window = wl->handles[i];
	    pr->path = NULL;

	    item_insert((void *) &process_handles, &nprocesses, hprocess);
	    nprocesses -= 1;
	    item_insert((void *) &process_records, &nprocesses, pr);
	};

	free(wl->handles);
    };

    free(wl);

    return count;
};
コード例 #3
0
ファイル: misc.c プロジェクト: nohuhu/TuTTY
HWND launch_putty(int action, char *path)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    DWORD wait;
    HWND pwin;
    struct process_record *pr;
    char buf[BUFSIZE];

    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);

    memset(&pi, 0, sizeof(PROCESS_INFORMATION));

    sprintf(buf, "%s -%s \"%s\"", config->putty_path,
	    action ? "edit" : "load", path);

    if (!CreateProcess(config->putty_path, buf, NULL, NULL,
		       FALSE, 0, NULL, NULL, &si, &pi))
	return NULL;

    wait = WaitForInputIdle(pi.hProcess, LAUNCH_TIMEOUT);

    if (wait != 0) {
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	return NULL;
    };

    CloseHandle(pi.hThread);

    pwin = NULL;
    EnumThreadWindows(pi.dwThreadId, FindPuttyWindowCallback, (LPARAM) &pwin);

    if (!pwin) {
	CloseHandle(pi.hProcess);
	return NULL;
    };

    pr = (struct process_record *) malloc(sizeof(struct process_record));
    pr->pid = pi.dwProcessId;
    pr->tid = pi.dwThreadId;
    pr->hprocess = pi.hProcess;
    pr->window = pwin;
    pr->path = dupstr(path);

    item_insert((void *) &process_handles, &nprocesses, pi.hProcess);
    nprocesses -= 1;
    item_insert((void *) &process_records, &nprocesses, pr);

    return pwin;
};
コード例 #4
0
ファイル: cmd_list.c プロジェクト: huayl/pelikan
void
cmd_list_create(struct response *rsp, struct request *req, struct command *cmd)
{
    struct item *it;
    struct bstring *key = _get_key(req);
    struct element *reply = (struct element *)array_push(rsp->token);

    INCR(process_metrics, list_create);

    it = _add_key(rsp, key);
    if (it == NULL) {
        log_debug("command '%.*s' '%.*s' failed: cannot store", cmd->bstr.len,
                cmd->bstr.data, key->len, key->data);
        return;
    }

    /* initialize data structure */
    ziplist_reset((ziplist_p)item_data(it));
    it->vlen = ZIPLIST_HEADER_SIZE;

    /* link into index */
    item_insert(it, key);

    rsp->type = reply->type = ELEM_STR;
    reply->bstr = str2bstr(RSP_OK);

    log_verb("command '%.*s' '%.*s' succeeded", cmd->bstr.len, cmd->bstr.data,
            key->len, key->data);
}
コード例 #5
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
static void leak_check(void)
{
	RADIX_TREE(tree, GFP_KERNEL);

	item_insert(&tree, 1000000);
	item_delete(&tree, 1000000);
	item_kill_tree(&tree);
}
コード例 #6
0
ファイル: main.c プロジェクト: AlexShiLucky/linux
void add_and_check(void)
{
	RADIX_TREE(tree, GFP_KERNEL);

	item_insert(&tree, 44);
	item_check_present(&tree, 44);
	item_check_absent(&tree, 43);
	item_kill_tree(&tree);
}
コード例 #7
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
static void __leak_check(void)
{
	RADIX_TREE(tree, GFP_KERNEL);

	printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated);
	item_insert(&tree, 1000000);
	printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated);
	item_delete(&tree, 1000000);
	printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated);
	item_kill_tree(&tree);
	printf("%d: nr_allocated=%d\n", __LINE__, nr_allocated);
}
コード例 #8
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
/*
 * Check that tags propagate correctly when extending a tree.
 */
static void extend_checks(void)
{
	RADIX_TREE(tree, GFP_KERNEL);

	item_insert(&tree, 43);
	assert(item_tag_get(&tree, 43, 0) == 0);
	item_tag_set(&tree, 43, 0);
	assert(item_tag_get(&tree, 43, 0) == 1);
	item_insert(&tree, 1000000);
	assert(item_tag_get(&tree, 43, 0) == 1);

	item_insert(&tree, 0);
	item_tag_set(&tree, 0, 0);
	item_delete(&tree, 1000000);
	assert(item_tag_get(&tree, 43, 0) != 0);
	item_delete(&tree, 43);
	assert(item_tag_get(&tree, 43, 0) == 0);	/* crash */
	assert(item_tag_get(&tree, 0, 0) == 1);

	verify_tag_consistency(&tree, 0);

	item_kill_tree(&tree);
}
コード例 #9
0
ファイル: tag_check.c プロジェクト: 020gzh/linux
static void
__simple_checks(struct radix_tree_root *tree, unsigned long index, int tag)
{
	int ret;

	item_check_absent(tree, index);
	assert(item_tag_get(tree, index, tag) == 0);

	item_insert(tree, index);
	assert(item_tag_get(tree, index, tag) == 0);
	item_tag_set(tree, index, tag);
	ret = item_tag_get(tree, index, tag);
	assert(ret != 0);
	ret = item_delete(tree, index);
	assert(ret != 0);
	item_insert(tree, index);
	ret = item_tag_get(tree, index, tag);
	assert(ret == 0);
	ret = item_delete(tree, index);
	assert(ret != 0);
	ret = item_delete(tree, index);
	assert(ret == 0);
}
コード例 #10
0
ファイル: main.c プロジェクト: AlexShiLucky/linux
void dynamic_height_check(void)
{
	int i;
	RADIX_TREE(tree, GFP_KERNEL);
	tree_verify_min_height(&tree, 0);

	item_insert(&tree, 42);
	tree_verify_min_height(&tree, 42);

	item_insert(&tree, 1000000);
	tree_verify_min_height(&tree, 1000000);

	assert(item_delete(&tree, 1000000));
	tree_verify_min_height(&tree, 42);

	assert(item_delete(&tree, 42));
	tree_verify_min_height(&tree, 0);

	for (i = 0; i < 1000; i++) {
		item_insert(&tree, i);
		tree_verify_min_height(&tree, i);
	}

	i--;
	for (;;) {
		assert(item_delete(&tree, i));
		if (i == 0) {
			tree_verify_min_height(&tree, 0);
			break;
		}
		i--;
		tree_verify_min_height(&tree, i);
	}

	item_kill_tree(&tree);
}
コード例 #11
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
/*
 * Check that tags propagate correctly when contracting a tree.
 */
static void contract_checks(void)
{
	struct item *item;
	int tmp;
	RADIX_TREE(tree, GFP_KERNEL);

	tmp = 1<<RADIX_TREE_MAP_SHIFT;
	item_insert(&tree, tmp);
	item_insert(&tree, tmp+1);
	item_tag_set(&tree, tmp, 0);
	item_tag_set(&tree, tmp, 1);
	item_tag_set(&tree, tmp+1, 0);
	item_delete(&tree, tmp+1);
	item_tag_clear(&tree, tmp, 1);

	assert(radix_tree_gang_lookup_tag(&tree, (void **)&item, 0, 1, 0) == 1);
	assert(radix_tree_gang_lookup_tag(&tree, (void **)&item, 0, 1, 1) == 0);

	assert(item_tag_get(&tree, tmp, 0) == 1);
	assert(item_tag_get(&tree, tmp, 1) == 0);

	verify_tag_consistency(&tree, 0);
	item_kill_tree(&tree);
}
コード例 #12
0
ファイル: tag_check.c プロジェクト: 020gzh/linux
static void single_check(void)
{
	struct item *items[BATCH];
	RADIX_TREE(tree, GFP_KERNEL);
	int ret;

	item_insert(&tree, 0);
	item_tag_set(&tree, 0, 0);
	ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0);
	assert(ret == 1);
	ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 1, BATCH, 0);
	assert(ret == 0);
	verify_tag_consistency(&tree, 0);
	verify_tag_consistency(&tree, 1);
	item_kill_tree(&tree);
}
コード例 #13
0
ファイル: main.c プロジェクト: 020gzh/linux
void __gang_check(unsigned long middle, long down, long up, int chunk, int hop)
{
	long idx;
	RADIX_TREE(tree, GFP_KERNEL);

	middle = 1 << 30;

	for (idx = -down; idx < up; idx++)
		item_insert(&tree, middle + idx);

	item_check_absent(&tree, middle - down - 1);
	for (idx = -down; idx < up; idx++)
		item_check_present(&tree, middle + idx);
	item_check_absent(&tree, middle + up);

	item_gang_check_present(&tree, middle - down,
			up + down, chunk, hop);
	item_full_scan(&tree, middle - down, down + up, chunk);
	item_kill_tree(&tree);
}
コード例 #14
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
static void single_check(void)
{
	struct item *items[BATCH];
	RADIX_TREE(tree, GFP_KERNEL);
	int ret;
	unsigned long first = 0;

	item_insert(&tree, 0);
	item_tag_set(&tree, 0, 0);
	ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0);
	assert(ret == 1);
	ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 1, BATCH, 0);
	assert(ret == 0);
	verify_tag_consistency(&tree, 0);
	verify_tag_consistency(&tree, 1);
	ret = tag_tagged_items(&tree, NULL, first, 10, 10, 0, 1);
	assert(ret == 1);
	ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 1);
	assert(ret == 1);
	item_tag_clear(&tree, 0, 0);
	ret = radix_tree_gang_lookup_tag(&tree, (void **)items, 0, BATCH, 0);
	assert(ret == 0);
	item_kill_tree(&tree);
}
コード例 #15
0
void fp_Tree::list_insert(const vector<int> & v) {
	int now = 0;
	for(int i = 1 ; i < v.size() ; ++i) {
		now = item_insert(v[i] , now);
	}
}
コード例 #16
0
ファイル: item.cpp プロジェクト: Gamesjiazhi/rwproject
// 创建道具
int item_create( int actor_index, int itemkind, int itemnum, ItemOut *pOut )
{
	if ( actor_index < 0 || actor_index >= g_maxactornum )
		return -1;
	if ( itemkind <= 0 || itemkind >= g_itemkindnum )
		return -1;
	if ( itemnum <= 0 )
		return -1;
	Item * pitem = NULL;
	int find_offset = 0;
	int remain_item = 0;
	int remain_count = 0;
	int totle_remain = 0;

	int item_offset;
	int tmpi, tmpj;
	int tmpmin, tmpmax;
	short itemtype;

	Actor *pActor = &g_actors[actor_index];

	while ( 1 )
	{
		// 找一个可以存放itemkind的空位置
		remain_item = _item_find_empty( pActor, itemkind, &find_offset );
		if ( remain_item <= 0 )
			return -1;
		if ( totle_remain + remain_item > itemnum )
			remain_item = itemnum - totle_remain;
		pOut[remain_count].m_item_offset = (find_offset < MAX_ACTOR_ITEMNUM) ? find_offset : find_offset - MAX_ACTOR_ITEMNUM;
		pOut[remain_count].m_count = remain_item;
		pOut[remain_count].m_itemkind = itemkind;
		remain_count++;
		find_offset++;
		totle_remain += remain_item;
		if ( totle_remain >= itemnum )
			break;
	}

	for ( tmpi = 0; tmpi < remain_count; tmpi++ )
	{
		item_offset = pOut[tmpi].m_item_offset;
		remain_item = pOut[tmpi].m_count;
		if ( item_offset >= 0 && item_offset < MAX_ACTOR_ITEMNUM )
			pitem = &pActor->item[item_offset];
		else
			continue;

		if ( pitem->m_num > 0 )
			pitem->m_num += remain_item;
		else
		{
			memset( pitem, 0, sizeof(Item) );
			pitem->m_kind = g_itemkind[itemkind].m_kind;
			pitem->m_num = remain_item;
			itemtype = item_gettype( pitem->m_kind );
			if ( itemtype >= ITEM_TYPE_EQUIP1 && itemtype <= ITEM_TYPE_EQUIP10 )
			{ // 如果是装备
				equip_create( actor_index, itemkind, item_offset );
			}
			else
			{ // 其它道具
				for ( tmpj = 0; tmpj < ITEM_ABILITY_NUM; tmpj++ )
				{
					pitem->m_ability[tmpj] = g_itemkind[itemkind].m_ability[tmpj];
					tmpmin = g_itemkind[itemkind].m_value_min[tmpj];
					tmpmax = g_itemkind[itemkind].m_value_max[tmpj];
					if ( tmpmin == tmpmax )
						pitem->m_value[tmpj] = tmpmin;
					else if ( tmpmax - tmpmin < 3 )
						pitem->m_value[tmpj] = tmpmin + rand() % (tmpmax - tmpmin + 1);
					else
						pitem->m_value[tmpj] = tmpmin + rand() % (tmpmax - tmpmin + 1);
				}

			}

			// 颜色 如果颜色信息有意义,以当前为主,否则为0
			if ( g_itemkind[itemkind].m_color_level >= 0 && pitem->m_color_level <= 0 )
				pitem->m_color_level = g_itemkind[itemkind].m_color_level;

			// 插入这个数据到数据库
			item_insert( actor_index, item_offset );
		}
	}
	return remain_count;
}
コード例 #17
0
ファイル: tag_check.c プロジェクト: AshishNamdev/linux
static void do_thrash(struct radix_tree_root *tree, char *thrash_state, int tag)
{
	int insert_chunk;
	int delete_chunk;
	int tag_chunk;
	int untag_chunk;
	int total_tagged = 0;
	int total_present = 0;

	for (insert_chunk = 1; insert_chunk < THRASH_SIZE; insert_chunk *= N)
	for (delete_chunk = 1; delete_chunk < THRASH_SIZE; delete_chunk *= N)
	for (tag_chunk = 1; tag_chunk < THRASH_SIZE; tag_chunk *= N)
	for (untag_chunk = 1; untag_chunk < THRASH_SIZE; untag_chunk *= N) {
		int i;
		unsigned long index;
		int nr_inserted = 0;
		int nr_deleted = 0;
		int nr_tagged = 0;
		int nr_untagged = 0;
		int actual_total_tagged;
		int actual_total_present;

		for (i = 0; i < insert_chunk; i++) {
			index = rand() % THRASH_SIZE;
			if (thrash_state[index] != NODE_ABSENT)
				continue;
			item_check_absent(tree, index);
			item_insert(tree, index);
			assert(thrash_state[index] != NODE_PRESENT);
			thrash_state[index] = NODE_PRESENT;
			nr_inserted++;
			total_present++;
		}

		for (i = 0; i < delete_chunk; i++) {
			index = rand() % THRASH_SIZE;
			if (thrash_state[index] == NODE_ABSENT)
				continue;
			item_check_present(tree, index);
			if (item_tag_get(tree, index, tag)) {
				assert(thrash_state[index] == NODE_TAGGED);
				total_tagged--;
			} else {
				assert(thrash_state[index] == NODE_PRESENT);
			}
			item_delete(tree, index);
			assert(thrash_state[index] != NODE_ABSENT);
			thrash_state[index] = NODE_ABSENT;
			nr_deleted++;
			total_present--;
		}

		for (i = 0; i < tag_chunk; i++) {
			index = rand() % THRASH_SIZE;
			if (thrash_state[index] != NODE_PRESENT) {
				if (item_lookup(tree, index))
					assert(item_tag_get(tree, index, tag));
				continue;
			}
			item_tag_set(tree, index, tag);
			item_tag_set(tree, index, tag);
			assert(thrash_state[index] != NODE_TAGGED);
			thrash_state[index] = NODE_TAGGED;
			nr_tagged++;
			total_tagged++;
		}

		for (i = 0; i < untag_chunk; i++) {
			index = rand() % THRASH_SIZE;
			if (thrash_state[index] != NODE_TAGGED)
				continue;
			item_check_present(tree, index);
			assert(item_tag_get(tree, index, tag));
			item_tag_clear(tree, index, tag);
			item_tag_clear(tree, index, tag);
			assert(thrash_state[index] != NODE_PRESENT);
			thrash_state[index] = NODE_PRESENT;
			nr_untagged++;
			total_tagged--;
		}

		actual_total_tagged = 0;
		actual_total_present = 0;
		for (index = 0; index < THRASH_SIZE; index++) {
			switch (thrash_state[index]) {
			case NODE_ABSENT:
				item_check_absent(tree, index);
				break;
			case NODE_PRESENT:
				item_check_present(tree, index);
				assert(!item_tag_get(tree, index, tag));
				actual_total_present++;
				break;
			case NODE_TAGGED:
				item_check_present(tree, index);
				assert(item_tag_get(tree, index, tag));
				actual_total_present++;
				actual_total_tagged++;
				break;
			}
		}

		gang_check(tree, thrash_state, tag);

		printf("%d(%d) %d(%d) %d(%d) %d(%d) / "
				"%d(%d) present, %d(%d) tagged\n",
			insert_chunk, nr_inserted,
			delete_chunk, nr_deleted,
			tag_chunk, nr_tagged,
			untag_chunk, nr_untagged,
			total_present, actual_total_present,
			total_tagged, actual_total_tagged);
	}
}
コード例 #18
0
ファイル: main.c プロジェクト: AlexShiLucky/linux
void copy_tag_check(void)
{
	RADIX_TREE(tree, GFP_KERNEL);
	unsigned long idx[ITEMS];
	unsigned long start, end, count = 0, tagged, cur, tmp;
	int i;

//	printf("generating radix tree indices...\n");
	start = rand();
	end = rand();
	if (start > end && (rand() % 10)) {
		cur = start;
		start = end;
		end = cur;
	}
	/* Specifically create items around the start and the end of the range
	 * with high probability to check for off by one errors */
	cur = rand();
	if (cur & 1) {
		item_insert(&tree, start);
		if (cur & 2) {
			if (start <= end)
				count++;
			item_tag_set(&tree, start, 0);
		}
	}
	if (cur & 4) {
		item_insert(&tree, start-1);
		if (cur & 8)
			item_tag_set(&tree, start-1, 0);
	}
	if (cur & 16) {
		item_insert(&tree, end);
		if (cur & 32) {
			if (start <= end)
				count++;
			item_tag_set(&tree, end, 0);
		}
	}
	if (cur & 64) {
		item_insert(&tree, end+1);
		if (cur & 128)
			item_tag_set(&tree, end+1, 0);
	}

	for (i = 0; i < ITEMS; i++) {
		do {
			idx[i] = rand();
		} while (item_lookup(&tree, idx[i]));

		item_insert(&tree, idx[i]);
		if (rand() & 1) {
			item_tag_set(&tree, idx[i], 0);
			if (idx[i] >= start && idx[i] <= end)
				count++;
		}
/*		if (i % 1000 == 0)
			putchar('.'); */
	}

//	printf("\ncopying tags...\n");
	tagged = tag_tagged_items(&tree, start, end, ITEMS, XA_MARK_0, XA_MARK_1);

//	printf("checking copied tags\n");
	assert(tagged == count);
	check_copied_tags(&tree, start, end, idx, ITEMS, 0, 1);

	/* Copy tags in several rounds */
//	printf("\ncopying tags...\n");
	tmp = rand() % (count / 10 + 2);
	tagged = tag_tagged_items(&tree, start, end, tmp, XA_MARK_0, XA_MARK_2);
	assert(tagged == count);

//	printf("%lu %lu %lu\n", tagged, tmp, count);
//	printf("checking copied tags\n");
	check_copied_tags(&tree, start, end, idx, ITEMS, 0, 2);
	verify_tag_consistency(&tree, 0);
	verify_tag_consistency(&tree, 1);
	verify_tag_consistency(&tree, 2);
//	printf("\n");
	item_kill_tree(&tree);
}
コード例 #19
0
ファイル: item.c プロジェクト: huayl/pelikan
item_rstatus_e
item_annex(struct item *oit, const struct bstring *key, const struct bstring
        *val, bool append)
{
    item_rstatus_e status = ITEM_OK;
    struct item *nit = NULL;
    uint8_t id;
    uint32_t ntotal = oit->vlen + val->len;

    id = item_slabid(oit->klen, ntotal, oit->olen);
    if (id == SLABCLASS_INVALID_ID) {
        log_info("client error: annex operation results in oversized item with"
                   "key size %"PRIu8" old value size %"PRIu32" and new value "
                   "size %"PRIu32, oit->klen, oit->vlen, ntotal);

        return ITEM_EOVERSIZED;
    }

    if (append) {
        /* if it is large enough to hold the extra data and left-aligned,
         * which is the default behavior, we copy the delta to the end of
         * the existing data. Otherwise, allocate a new item and store the
         * payload left-aligned.
         */
        if (id == oit->id && !(oit->is_raligned)) {
            cc_memcpy(item_data(oit) + oit->vlen, val->data, val->len);
            oit->vlen = ntotal;
            INCR_N(slab_metrics, item_keyval_byte, val->len);
            INCR_N(slab_metrics, item_val_byte, val->len);
            item_set_cas(oit);
        } else {
            status = _item_alloc(&nit, oit->klen, ntotal, oit->olen);
            if (status != ITEM_OK) {
                log_debug("annex failed due to failure to allocate new item");
                return status;
            }
            _copy_key_item(nit, oit);
            nit->expire_at = oit->expire_at;
            nit->create_at = time_proc_sec();
            item_set_cas(nit);
            /* value is left-aligned */
            cc_memcpy(item_data(nit), item_data(oit), oit->vlen);
            cc_memcpy(item_data(nit) + oit->vlen, val->data, val->len);
            nit->vlen = ntotal;
            item_insert(nit, key);
        }
    } else {
        /* if oit is large enough to hold the extra data and is already
         * right-aligned, we copy the delta to the front of the existing
         * data. Otherwise, allocate a new item and store the payload
         * right-aligned, assuming more prepends will happen in the future.
         */
        if (id == oit->id && oit->is_raligned) {
            cc_memcpy(item_data(oit) - val->len, val->data, val->len);
            oit->vlen = ntotal;
            INCR_N(slab_metrics, item_keyval_byte, val->len);
            INCR_N(slab_metrics, item_val_byte, val->len);
            item_set_cas(oit);
        } else {
            status = _item_alloc(&nit, oit->klen, ntotal, oit->olen);
            if (status != ITEM_OK) {
                log_debug("annex failed due to failure to allocate new item");
                return status;
            }
            _copy_key_item(nit, oit);
            nit->expire_at = oit->expire_at;
            nit->create_at = time_proc_sec();
            item_set_cas(nit);
            /* value is right-aligned */
            nit->is_raligned = 1;
            cc_memcpy(item_data(nit) - ntotal, val->data, val->len);
            cc_memcpy(item_data(nit) - oit->vlen, item_data(oit), oit->vlen);
            nit->vlen = ntotal;
            item_insert(nit, key);
        }
    }

    log_verb("annex to it %p of id %"PRIu8", new it at %p", oit, oit->id,
            nit ? oit : nit);

    return status;
}