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