1 /*************************************************************************************************
2  * Comparison test of SQLite and Tokyo Cabinet
3  *************************************************************************************************/
4 
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include <sys/time.h>
11 #include <assert.h>
12 #include <sqlite3.h>
13 #include <tctdb.h>
14 
15 #define SQLFILE    "casket.sql"
16 #define TCTFILE    "casket.tct"
17 #define SQLBUFSIZ   1024
18 #define SAMPLENUM   10
19 #define RECORDNUM   1000000
20 
21 
22 /* function prototypes */
23 int main(int argc, char **argv);
24 static void test_sqlite(void);
25 static void test_tctdb(void);
26 static int myrand(void);
27 static int callback(void *opq, int argc, char **argv, char **colname);
28 
29 
30 /* main routine */
main(int argc,char ** argv)31 int main(int argc, char **argv){
32   test_sqlite();
33   test_tctdb();
34   return 0;
35 }
36 
37 
38 /* perform SQLite test */
test_sqlite(void)39 static void test_sqlite(void){
40   double sum = 0.0;
41   for(int i = 1; i <= SAMPLENUM; i++){
42     unlink(SQLFILE);
43     sync(); sync();
44     printf("SQLite write sample:%d ... ", i);
45     fflush(stdout);
46     double stime = tctime();
47     sqlite3 *db;
48     if(sqlite3_open(SQLFILE, &db) != 0) assert(!__LINE__);
49     char sql[SQLBUFSIZ], *errmsg;
50     sprintf(sql, "CREATE TABLE tbl ( k TEXT PRIMARY KEY, a TEXT, b INTEGER,"
51             " c TEXT, d INTEGER );");
52     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
53     sprintf(sql, "CREATE INDEX tbl_s ON tbl ( a );");
54     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
55     sprintf(sql, "CREATE INDEX tbl_n ON tbl ( b );");
56     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
57     sprintf(sql, "PRAGMA cache_size = %d;", RECORDNUM);
58     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
59     sprintf(sql, "BEGIN TRANSACTION;");
60     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
61     for(int j = 1; j <= RECORDNUM; j++){
62       sprintf(sql, "INSERT INTO tbl VALUES ( '%08d', '%08d', %d, '%08d', %d );",
63             j, j, myrand() % RECORDNUM, myrand() % RECORDNUM, j);
64       if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
65     }
66     sprintf(sql, "END TRANSACTION;");
67     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
68     sqlite3_close(db);
69     double etime = tctime() - stime;
70     printf("%.6f\n", etime);
71     sum += etime;
72   }
73   printf("SQLite write average: %.6f\n", sum / SAMPLENUM);
74   sum = 0.0;
75   for(int i = 1; i <= SAMPLENUM; i++){
76     sync(); sync();
77     printf("SQLite read sample:%d ... ", i);
78     fflush(stdout);
79     double stime = tctime();
80     sqlite3 *db;
81     if(sqlite3_open(SQLFILE, &db) != 0) assert(!__LINE__);
82     char sql[SQLBUFSIZ], *errmsg;
83     sprintf(sql, "PRAGMA cache_size = %d;", RECORDNUM);
84     if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
85     for(int j = 1; j <= RECORDNUM; j++){
86       sprintf(sql, "SELECT * FROM tbl WHERE a = '%08d';", myrand() % RECORDNUM + 1);
87       if(sqlite3_exec(db, sql, callback, 0, &errmsg) != SQLITE_OK) assert(!__LINE__);
88     }
89     sqlite3_close(db);
90     double etime = tctime() - stime;
91     printf("%.6f\n", etime);
92     sum += etime;
93   }
94   printf("SQLite read average: %.6f\n", sum / SAMPLENUM);
95 }
96 
97 
98 /* perform TCHDB test */
test_tctdb(void)99 static void test_tctdb(void){
100   double sum = 0.0;
101   for(int i = 1; i <= SAMPLENUM; i++){
102     unlink(TCTFILE);
103     sync(); sync();
104     printf("TCTDB write sample:%d ... ", i);
105     fflush(stdout);
106     double stime = tctime();
107     TCTDB *tdb = tctdbnew();
108     if(!tctdbtune(tdb, RECORDNUM * 2, -1, -1, 0)) assert(!__LINE__);
109     if(!tctdbsetcache(tdb, 0, RECORDNUM, RECORDNUM)) assert(!__LINE__);
110     if(!tctdbopen(tdb, TCTFILE, TDBOWRITER | TDBOCREAT | TDBOTRUNC)) assert(!__LINE__);
111     if(!tctdbsetindex(tdb, "a", TDBITLEXICAL)) assert(!__LINE__);
112     if(!tctdbsetindex(tdb, "b", TDBITDECIMAL)) assert(!__LINE__);
113     if(!tctdbtranbegin(tdb)) assert(!__LINE__);
114     char buf[SQLBUFSIZ];
115     int size;
116     for(int j = 1; j <= RECORDNUM; j++){
117       TCMAP *cols = tcmapnew2(7);
118       size = sprintf(buf, "%08d", j);
119       tcmapput(cols, "a", 1, buf, size);
120       size = sprintf(buf, "%d", myrand() % RECORDNUM);
121       tcmapput(cols, "b", 1, buf, size);
122       size = sprintf(buf, "%08d", myrand() % RECORDNUM);
123       tcmapput(cols, "c", 1, buf, size);
124       size = sprintf(buf, "%d", j);
125       tcmapput(cols, "d", 1, buf, size);
126       size = sprintf(buf, "%08d", j);
127       if(!tctdbput(tdb, buf, size, cols)) assert(!__LINE__);
128       tcmapdel(cols);
129     }
130     if(!tctdbtrancommit(tdb)) assert(!__LINE__);
131     if(!tctdbclose(tdb)) assert(!__LINE__);
132     tctdbdel(tdb);
133     double etime = tctime() - stime;
134     printf("%.6f\n", etime);
135     sum += etime;
136   }
137   printf("TCTDB write average: %.6f\n", sum / SAMPLENUM);
138   sum = 0.0;
139   for(int i = 1; i <= SAMPLENUM; i++){
140     sync(); sync();
141     printf("TCTDB read sample:%d ... ", i);
142     fflush(stdout);
143     double stime = tctime();
144     TCTDB *tdb = tctdbnew();
145     if(!tctdbsetcache(tdb, 0, RECORDNUM, RECORDNUM)) assert(!__LINE__);
146     if(!tctdbopen(tdb, TCTFILE, TDBOREADER)) assert(!__LINE__);
147     char buf[SQLBUFSIZ];
148     for(int j = 1; j <= RECORDNUM; j++){
149       TDBQRY *qry = tctdbqrynew(tdb);
150       sprintf(buf, "%08d", myrand() % RECORDNUM + 1);
151       tctdbqryaddcond(qry, "a", TDBQCSTREQ, buf);
152       TCLIST *res = tctdbqrysearch(qry);
153       for(int k = 0; k < tclistnum(res); k++){
154         int ksiz;
155         const char *kbuf = tclistval(res, k, &ksiz);
156         TCMAP *cols = tctdbget(tdb, kbuf, ksiz);
157         if(!cols) assert(!__LINE__);
158         tcmapdel(cols);
159       }
160       tclistdel(res);
161       tctdbqrydel(qry);
162     }
163     if(!tctdbclose(tdb)) assert(!__LINE__);
164     double etime = tctime() - stime;
165     printf("%.6f\n", etime);
166     sum += etime;
167   }
168   printf("TCTDB read average: %.6f\n", sum / SAMPLENUM);
169 }
170 
171 
172 /* generate a random number */
myrand(void)173 static int myrand(void){
174   static int cnt = 0;
175   return (lrand48() + cnt++) & 0x7FFFFFFF;
176 }
177 
178 
179 /* iterator of SQLite */
callback(void * opq,int argc,char ** argv,char ** colname)180 static int callback(void *opq, int argc, char **argv, char **colname){
181   return 0;
182 }
183 
184 
185 
186 /* END OF FILE */
187