Skip to content

Commit

Permalink
Simulate a huge (100K) insertions
Browse files Browse the repository at this point in the history
  • Loading branch information
symisc committed May 22, 2019
1 parent ad29814 commit a3223a5
Showing 1 changed file with 74 additions and 73 deletions.
147 changes: 74 additions & 73 deletions example/unqlite_huge.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* Compile this file together with the UnQLite database engine source code
* to generate the executable. For example:
* gcc -W -Wall -O6 unqlite_huge_insert.c unqlite.c -o unqlite_huge
* to generate the executable. For example:
* gcc -W -Wall -O6 unqlite_huge_insert.c unqlite.c -o unqlite_huge
*/
/*
* This simple program is a quick introduction on how to embed and start
Expand Down Expand Up @@ -29,7 +29,7 @@
*
* To start an in-memory database, invoke the program without arguments as follows:
*
* ./unqlite_huge
* ./unqlite_huge
*
* For an introduction to the UnQLite C/C++ interface, please refer to:
* http://unqlite.org/api_intro.html
Expand All @@ -43,14 +43,14 @@
* the Document-Store interface to UnQLite, please refer to:
* http://unqlite.org/jx9.html
*/
/* $SymiscID: unqlite_huge_insert.c v1.0 Solaris 2013-05-15 20:17 stable <chm@symisc.net> $ */
/*
* Make sure you have the latest release of UnQLite from:
* http://unqlite.org/downloads.html
*/
/* $SymiscID: unqlite_huge_insert.c v1.0 Solaris 2013-05-15 20:17 stable <chm@symisc.net> $ */
/*
* Make sure you have the latest release of UnQLite from:
* http://unqlite.org/downloads.html
*/
#include <stdio.h> /* puts() */
#include <stdlib.h> /* exit() */
/* Make sure this header file is available.*/
/* Make sure this header file is available.*/
#include "unqlite.h"
/*
* Banner.
Expand All @@ -64,20 +64,21 @@ static const char zBanner[] = {
/*
* Extract the database error log and exit.
*/
static void Fatal(unqlite *pDb,const char *zMsg)
static void Fatal(unqlite *pDb, const char *zMsg)
{
if( pDb ){
if (pDb) {
const char *zErr;
int iLen = 0; /* Stupid cc warning */

/* Extract the database error log */
unqlite_config(pDb,UNQLITE_CONFIG_ERR_LOG,&zErr,&iLen);
if( iLen > 0 ){
unqlite_config(pDb, UNQLITE_CONFIG_ERR_LOG, &zErr, &iLen);
if (iLen > 0) {
/* Output the DB error log */
puts(zErr); /* Always null termniated */
puts(zErr); /* Always null terminated */
}
}else{
if( zMsg ){
}
else {
if (zMsg) {
puts(zMsg);
}
}
Expand All @@ -87,115 +88,115 @@ static void Fatal(unqlite *pDb,const char *zMsg)
exit(0);
}
/* Forward declaration: Data consumer callback */
static int DataConsumerCallback(const void *pData,unsigned int nDatalen,void *pUserData /* Unused */);
static int DataConsumerCallback(const void *pData, unsigned int nDatalen, void *pUserData /* Unused */);
/*
* Maximum records to be inserted in our database.
*/
#define MAX_RECORDS 100000

int main(int argc,char *argv[])
int main(int argc, char *argv[])
{
const char *zPath = ":mem:"; /* Assume an in-memory database */
int db_iterate = 0; /* TRUE to iterate over the inserted elements */
unqlite *pDb; /* Database handle */
char zKey[14]; /* Random generated key */
char zData[32]; /* Dummy data */
int i,rc;
int i, rc;

/* Process arguments */
for(i = 1 ; i < argc ; ++i ){
for (i = 1; i < argc; ++i) {
int c;
if( argv[i][0] != '-' ){
if (argv[i][0] != '-') {
/* Database file */
zPath = argv[i];
continue;
}
c = argv[i][1];
if( c == 'i' || c == 'I' ){
if (c == 'i' || c == 'I') {
/* Iterate over the inserted elements */
db_iterate = 1;
}
}
puts(zBanner);

/* Open our database */
rc = unqlite_open(&pDb,zPath,UNQLITE_OPEN_CREATE);
if( rc != UNQLITE_OK ){
Fatal(0,"Out of memory");
rc = unqlite_open(&pDb, zPath, UNQLITE_OPEN_CREATE);
if (rc != UNQLITE_OK) {
Fatal(0, "Out of memory");
}
printf("Starting insertions of %d random records...\n",MAX_RECORDS);

printf("Starting insertions of %d random records...\n", MAX_RECORDS);

/* Start the random insertions */
for( i = 0 ; i < MAX_RECORDS; ++i ){
/* Genearte the random key first */
unqlite_util_random_string(pDb,zKey,sizeof(zKey));
for (i = 0; i < MAX_RECORDS; ++i) {

/* Generate the random key first */
unqlite_util_random_string(pDb, zKey, sizeof(zKey));

/* Perform the insertion */
rc = unqlite_kv_store(pDb,zKey,sizeof(zKey),zData,sizeof(zData));
if( rc != UNQLITE_OK ){
rc = unqlite_kv_store(pDb, zKey, sizeof(zKey), zData, sizeof(zData));
if (rc != UNQLITE_OK) {
/* Something goes wrong */
break;
}

if( i == 79125 ){
if (i == 79125) {
/* Insert a sentinel record */

/* time(&tt); pTm = localtime(&tt); ... */
unqlite_kv_store_fmt(pDb,"sentinel",-1,"I'm a sentinel record inserted on %d:%d:%d\n",14,15,18); /* Dummy time */
unqlite_kv_store_fmt(pDb, "sentinel", -1, "I'm a sentinel record inserted on %d:%d:%d\n", 14, 15, 18); /* Dummy time */
}
}

/* If we are OK, then manually commit the transaction */
if( rc == UNQLITE_OK ){
/*
if (rc == UNQLITE_OK) {
/*
* In fact, a call to unqlite_commit() is not necessary since UnQLite
* will automatically commit the transaction during a call to unqlite_close().
*/
rc = unqlite_commit(pDb);
if( rc != UNQLITE_OK ){
if (rc != UNQLITE_OK) {
/* Rollback the transaction */
rc = unqlite_rollback(pDb);
}
}
if( rc != UNQLITE_OK ){

if (rc != UNQLITE_OK) {
/* Something goes wrong, extract the database error log and exit */
Fatal(pDb,0);
Fatal(pDb, 0);
}
puts("Done...Fetching the 'sentinel' record: ");

/* Fetch the sentinel */
rc = unqlite_kv_fetch_callback(pDb,"sentinel",-1,DataConsumerCallback,0);
if( rc != UNQLITE_OK ){
rc = unqlite_kv_fetch_callback(pDb, "sentinel", -1, DataConsumerCallback, 0);
if (rc != UNQLITE_OK) {
/* Can't happen */
Fatal(0,"Sentinel record not found");
Fatal(0, "Sentinel record not found");
}

if( db_iterate ){
if (db_iterate) {
/* Iterate over the inserted records */
unqlite_kv_cursor *pCur;

/* Allocate a new cursor instance */
rc = unqlite_kv_cursor_init(pDb,&pCur);
if( rc != UNQLITE_OK ){
Fatal(0,"Out of memory");
rc = unqlite_kv_cursor_init(pDb, &pCur);
if (rc != UNQLITE_OK) {
Fatal(0, "Out of memory");
}

/* Point to the first record */
unqlite_kv_cursor_first_entry(pCur);

/* Iterate over the entries */
while( unqlite_kv_cursor_valid_entry(pCur) ){
while (unqlite_kv_cursor_valid_entry(pCur)) {
int nKeyLen;
/* unqlite_int64 nDataLen; */

/* Consume the key */
unqlite_kv_cursor_key(pCur,0,&nKeyLen); /* Extract key length */
printf("\nKey ==> %u\n\t",nKeyLen);
unqlite_kv_cursor_key_callback(pCur,DataConsumerCallback,0);
unqlite_kv_cursor_key(pCur, 0, &nKeyLen); /* Extract key length */
printf("\nKey ==> %u\n\t", nKeyLen);
unqlite_kv_cursor_key_callback(pCur, DataConsumerCallback, 0);

/* Consume the data */
/*
unqlite_kv_cursor_data(pCur,0,&nDataLen);
Expand All @@ -209,7 +210,7 @@ int main(int argc,char *argv[])
}

/* Finally, Release our cursor */
unqlite_kv_cursor_release(pDb,pCur);
unqlite_kv_cursor_release(pDb, pCur);
}

/* All done, close our database */
Expand All @@ -230,28 +231,28 @@ int main(int argc,char *argv[])
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
/*
* 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.
*/
static int DataConsumerCallback(const void *pData,unsigned int nDatalen,void *pUserData /* Unused */)
/*
* 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.
*/
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 ){
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 ){
nWr = write(STDOUT_FILENO, pData, nDatalen);
if (nWr < 0) {
/* Abort processing */
return UNQLITE_ABORT;
}
Expand Down

0 comments on commit a3223a5

Please sign in to comment.