Unqlite

Unqlite相关的笔记

官网链接-unqlite_kv_fetch_callback
关于unqlite_kv_cursor_key和unqlite_kv_cursor_key_callback

  • unqlite_kv_cursor_key
int unqlite_kv_cursor_key(unqlite_kv_cursor *pCursor, void *pBuf, int *pnByte)
{
	int rc;
#ifdef UNTRUST
	if (pCursor == 0) {
		return UNQLITE_CORRUPT;
	}
#endif
	if (pBuf == 0) {
		/* Key length only */
		rc = pCursor->pStore->pIo->pMethods->xKeyLength(pCursor, pnByte);
	}
	else {
		SyBlob sBlob;
		if ((*pnByte) < 0) {
			return UNQLITE_CORRUPT;
		}
		/* Initialize the data consumer */
		SyBlobInitFromBuf(&sBlob, pBuf, (sxu32)(*pnByte));
		/* Consume the key */
		rc = pCursor->pStore->pIo->pMethods->xKey(pCursor, unqliteDataConsumer, &sBlob);
		/* Key length */
		*pnByte = SyBlobLength(&sBlob);
		/* Cleanup */
		SyBlobRelease(&sBlob);
	}
	return rc;
}

unqlite_kv_cursor_key源码如上,实现将pCursor对应的key值写到pBuf中。需要注意的是,该函数一开始执行判断if (pBuf == 0),然后将key值长度写到pnByte,如果pBuf!=0接着判断if ((*pnByte) < 0),这时才会把key值写到pBuf。也就是说,对pBufpnByte的写是分开的,如果传进来的pnByte没初始化,那么后面对pBuf的写就会出现错误(实际就是不会写)。因此,为了保证正确写pBuf,建议先传0到该函数以获取key值长度到pnByte,再来写pBuf。如下。

unqlite_kv_cursor_key(pCur_name, 0, &nKeyLen); // Extract key length
unqlite_kv_cursor_key(pCur_name, num, &nKeyLen); // consume the key

  • unqlite_kv_cursor_key_callback
int unqlite_kv_cursor_key_callback(unqlite_kv_cursor *pCursor, int(*xConsumer)(const void *, unsigned int, void *), void *pUserData)
{
	int rc;
#ifdef UNTRUST
	if (pCursor == 0) {
		return UNQLITE_CORRUPT;
	}
#endif
	/* Consume the key directly */
	rc = pCursor->pStore->pIo->pMethods->xKey(pCursor, xConsumer, pUserData);
	return rc;
}

demo里使用回调函数DataConsumerCallback,将key值定向到标准输出STD_OUTPUT_HANDLE

unqlite_kv_cursor_key_callback(pCur_name, DataConsumerCallback, 0);

static int DataConsumerCallback(const void *pData, unsigned int nDatalen, void *pUserData /* Unused */)
{
#ifdef __WINNT__
	BOOL rc;
	rc = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pData, (DWORD)nDatalen, 0, 0);
	if (!rc) {
		/* Abort processing */
		return UNQLITE_ABORT;
	}
#else
	ssize_t nWr;
	nWr = write(STDOUT_FILENO, pData, nDatalen);
	if (nWr < 0) {
		/* Abort processing */
		return UNQLITE_ABORT;
	}
#endif /* __WINT__ */

	/* All done, data was redirected to STDOUT */
	return UNQLITE_OK;
}

其中的注释值得关注,下面单独列出。

/*
  * Data consumer callback [unqlite_kv_fetch_callback(), unqlite_kv_cursor_key_callback(), etc.).
  *
  * Rather than allocating a static or dynamic buffer (Inefficient scenario for large data).
  * The caller simply need to supply a consumer callback which is responsible of consuming
  * the record data perhaps redirecting it (i.e. Record data) to its standard output (STDOUT),
  * disk file, connected peer and so forth.
  * Depending on how large the extracted data, the callback may be invoked more than once.
  */

这个注释非常非常关键,使用回调函数重定向数据到标准输出、磁盘文件、connected peer等,相比于上一种方法将数据写到pBuf回调函数在处理大数据方面会更加高效
当然,也可以使用回调函数将数据写道指定的buff中来,不过这样就得不偿失了。如下,提供一种思路。稍微修改函数DataConsumerCallback

#ifdef __WINNT__
	BOOL rc;
	rc = WriteFile(GetStdHandle(IGNORE), pData, (DWORD)nDatalen, 0, 0);
	strcpy_s((char *)pUserData, nDatalen, (char *)pData);
	if (!rc) {
		/* Abort processing */
		return UNQLITE_ABORT;
	}

unqlite_kv_cursor_key_callback(pCur_name, DataConsumerCallback, num);

将key值写到num

你可能感兴趣的:(嵌入式)