Browse Source

[2041] Initial SQLite benchmark implementation

Tomek Mrugalski 12 years ago
parent
commit
6c8b787f32

+ 11 - 1
tests/tools/dhcp-ubench/Makefile

@@ -1,8 +1,12 @@
 MYSQL_CFLAGS=`mysql_config --cflags`
 MYSQL_LDFLAGS=`mysql_config --libs`
 CFLAGS=-g -O0
+LDFLAGS=-lrt
 
-all: mysql_ubench
+SQLITE_CFLAGS=`pkg-config sqlite3 --cflags` $(LDFLAGS)
+SQLITE_LDFLAGS=`pkg-config sqlite3 --libs`
+
+all: mysql_ubench sqlite_ubench
 
 mysql_ubench.o: mysql_ubench.cc mysql_ubench.h
 	$(CXX) $< -c $(CFLAGS) $(MYSQL_CFLAGS)
@@ -13,5 +17,11 @@ benchmark.o: benchmark.cc benchmark.h
 mysql_ubench: mysql_ubench.o benchmark.o
 	$(CXX) $< benchmark.o -o mysql_ubench $(CFLAGS) $(MYSQL_CFLAGS) $(MYSQL_LDFLAGS)
 
+sqlite_ubench.o: sqlite_ubench.cc sqlite_ubench.h
+	$(CXX) $< -c $(CFLAGS) $(SQLLITE_CFLAGS)
+
+sqlite_ubench: sqlite_ubench.o benchmark.o
+	$(CXX) $< benchmark.o -o sqlite_ubench $(CFLAGS) $(SQLITE_CFLAGS) $(SQLITE_LDFLAGS)
+
 clean:
 	rm -f mysql_ubench *.o

+ 3 - 0
tests/tools/dhcp-ubench/benchmark.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <iostream>
+#include <stdlib.h>
 #include <string.h>
 #include "benchmark.h"
 
@@ -50,6 +51,8 @@ void uBenchmark::print_clock(const std::string& operation, uint32_t num,
 
 int uBenchmark::run() {
 
+    srandom(time(NULL));
+
     try {
         connect();
 

+ 0 - 2
tests/tools/dhcp-ubench/mysql_ubench.cc

@@ -42,8 +42,6 @@ void MySQL_uBenchmark::failure(const char* operation) {
 
 void MySQL_uBenchmark::connect() {
 
-    srandom(time(NULL));
-
     Conn_ = mysql_init(NULL);
     if (!Conn_) {
         failure("initializing MySQL library");

+ 85 - 0
tests/tools/dhcp-ubench/sqlite.schema

@@ -0,0 +1,85 @@
+DROP TABLE lease4;
+DROP TABLE lease6;
+DROP TABLE host;
+
+CREATE TABLE lease4 (
+
+    -- Primary key (serial = BININT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE)
+    lease_id SERIAL,
+    addr INT UNSIGNED UNIQUE,
+
+    -- The largest hardware address is for Infiniband (20 bytes)
+    hwaddr VARCHAR(20),
+
+    -- The largest client-id is DUID in DHCPv6 - up to 128 bytes
+    client_id VARCHAR(128),
+
+    -- Expressed in seconds
+    valid_lft INT,
+
+    -- Expressed in seconds,
+    recycle_time INT DEFAULT 0,
+
+    cltt TIMESTAMP,
+
+    pool_id int,
+
+    fixed BOOL,
+
+    -- DDNS stuff
+    hostname VARCHAR(255),
+    fqdn_fwd BOOL DEFAULT false,
+    fqdn_rev BOOL DEFAULT false,
+
+    options TEXT,
+    comments TEXT
+);
+
+CREATE TABLE lease6 (
+
+    -- Primary key (serial = BININT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE)
+    lease_id SERIAL,
+    addr CHAR(16) UNIQUE,
+
+    -- The largest hardware address is for Infiniband (20 bytes)
+    hwaddr VARCHAR(20),
+
+    -- The largest client-id is DUID in DHCPv6 - up to 128 bytes
+    client_id VARCHAR(128),
+
+    iaid int unsigned,
+
+    -- Used for IA_PD only (tinyint = 0..255)
+    prefix_len TINYINT unsigned,
+
+    -- Expressed in seconds
+    preferred_lft INT,
+
+    -- Expressed in seconds
+    valid_lft INT,
+
+    -- Expressed in seconds,
+    recycle_time INT DEFAULT 0,
+
+    cltt TIMESTAMP,
+
+    pool_id int,
+
+    fixed BOOL DEFAULT false,
+
+    hostname VARCHAR(255),
+    fqdn_fwd BOOL DEFAULT false,
+    fqdn_rev BOOL DEFAULT false,
+
+    options TEXT,
+    comments TEXT
+);
+
+CREATE TABLE host (
+    address BIGINT NULL,
+    address6 BIGINT NULL,
+    prefix6 BIGINT NULL,
+    hostname VARCHAR(255),
+    options TEXT,
+    comments TEXT
+);

+ 245 - 0
tests/tools/dhcp-ubench/sqlite_ubench.cc

@@ -0,0 +1,245 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sstream>
+#include <iostream>
+#include <sqlite3.h>
+#include "sqlite_ubench.h"
+
+using namespace std;
+
+SQLite_uBenchmark::SQLite_uBenchmark(const string& filename,
+                                   uint32_t num_iterations)
+    :uBenchmark(num_iterations), Filename_(filename), DB_(NULL) {
+
+}
+
+void SQLite_uBenchmark::failure(const char* operation) {
+    throw string(operation);
+}
+
+void SQLite_uBenchmark::connect() {
+    int result = sqlite3_open(Filename_.c_str(), &DB_);
+    if (result) {
+        sqlite3_open(Filename_.c_str(), &DB_);
+        failure("Failed to open DB file");
+    }
+
+    sqlite3_exec(DB_, "DELETE FROM lease4", 0, 0, 0);
+}
+
+void SQLite_uBenchmark::disconnect() {
+    if (DB_) {
+        sqlite3_close(DB_);
+        DB_ = NULL;
+    }
+}
+
+void SQLite_uBenchmark::createLease4Test() {
+    if (!DB_) {
+        throw "SQLite connection is closed.";
+    }
+
+    uint32_t addr = BASE_ADDR4; // Let's start with 1.0.0.0 address
+    char hwaddr[20];
+    uint8_t hwaddr_len = 20; // not a real field
+    char client_id[128];
+    uint8_t client_id_len = 128;
+    uint32_t valid_lft = 1000;  // we can use the same value for all leases
+    uint32_t recycle_time = 0;  // not supported in any foresable future,
+                                // so keep this as 0
+    string cltt = "now"; // timestamp
+    uint32_t pool_id = 0; // let's use pools 0-99
+    bool fixed = false;   //
+    string hostname("foo");      // will generate it dynamically
+    bool fqdn_fwd = true; // let's pretend to do AAAA update
+    bool fqdn_rev = true; // let's pretend to do PTR update
+
+    printf("CREATE:   ");
+
+    for (uint8_t i = 0; i < 20; i++) {
+        hwaddr[i] = 65 + i;
+    }
+    hwaddr[19] = 0; // workaround
+
+    for (uint8_t i = 0; i < 128; i++) {
+        client_id[i] = 33 + i;
+    }
+    client_id[6] = 'X';
+    client_id[127] = 0; // workaround
+
+    for (uint32_t i = 0; i < Num_; i++) {
+
+        stringstream cltt;
+        cltt << "2012-07-11 15:43:" << (i % 60);
+
+        addr++;
+        char * errorMsg = NULL;
+
+        // the first address is 1.0.0.0.
+        char query[2000], * end;
+        /// @todo: Encode HWADDR and CLIENT-ID properly
+        sprintf(query, "INSERT INTO lease4(addr,hwaddr,client_id,"
+               "valid_lft,recycle_time,cltt,pool_id,fixed,hostname,"
+               "fqdn_fwd,fqdn_rev) VALUES(%u,'%s','%s',%d,%d,'%s',%d,'%s','%s','%s','%s');",
+               addr, hwaddr, client_id, valid_lft, recycle_time,
+               cltt.str().c_str(), pool_id, (fixed?"true":"false"),
+               hostname.c_str(), (fqdn_fwd?"true":"false"), (fqdn_rev?"true":"false"));
+        // printf("QUERY=[%s]\n", query);
+
+        int result = sqlite3_exec(DB_, query, NULL, 0, &errorMsg);
+
+        if (result != SQLITE_OK) {
+            stringstream tmp;
+            tmp << "INSERT error:" << errorMsg;
+            failure(tmp.str().c_str());
+        } else {
+            printf(".");
+        };
+
+    }
+    printf("\n");
+}
+
+static int search_callback(void *counter, int argc, char **argv, char **azColName){
+
+    int * cnt = static_cast<int*>(counter);
+    (*cnt)++;
+
+#if 0
+    int i;
+    for(i=0; i<argc; i++){
+        printf("%s=%s ", azColName[i], argv[i] ? argv[i] : "NULL");
+    }
+    printf("\n");
+#endif
+    return 0;
+}
+
+void SQLite_uBenchmark::searchLease4Test() {
+    if (!DB_) {
+        throw "SQLite connection is closed.";
+    }
+
+    // this formula should roughly find something a lease in 90% cases
+    float hitRatio = 0.5;
+
+    printf("RETRIEVE: ");
+
+    for (uint32_t i = 0; i < Num_; i++) {
+
+        uint32_t x = BASE_ADDR4 + random() % int(Num_ / hitRatio);
+
+        char * errorMsg = NULL;
+
+        int cnt = 0;
+
+        char query[2000];
+        sprintf(query, "SELECT lease_id,addr,hwaddr,client_id,valid_lft,"
+                "cltt,pool_id,fixed,hostname,fqdn_fwd,fqdn_rev "
+                "FROM lease4 where addr=%d", x);
+        int result = sqlite3_exec(DB_, query, search_callback, &cnt, &errorMsg);
+        if (result != SQLITE_OK) {
+            stringstream tmp;
+            tmp << "SELECT failed: " << errorMsg;
+            failure(tmp.str().c_str());
+        }
+
+        if (cnt) {
+            printf(".");
+        } else {
+            printf("X");
+        }
+
+    }
+
+    printf("\n");
+}
+
+void SQLite_uBenchmark::updateLease4Test() {
+    if (!DB_) {
+        throw "SQLite connection is closed.";
+    }
+
+    printf("UPDATE:   ");
+
+    for (uint32_t i = 0; i < Num_; i++) {
+
+        uint32_t x = BASE_ADDR4 + random() % Num_;
+
+        char * errorMsg = NULL;
+        char query[2000];
+        sprintf(query, "UPDATE lease4 SET valid_lft=1002, cltt='now' WHERE addr=%d", x);
+
+        int result = sqlite3_exec(DB_, query, NULL /* no callback here*/, 0, &errorMsg);
+        if (result != SQLITE_OK) {
+            stringstream tmp;
+            tmp << "UPDATE error:" << errorMsg;
+            failure(tmp.str().c_str());
+        }
+        printf(".");
+    }
+
+    printf("\n");
+}
+
+void SQLite_uBenchmark::deleteLease4Test() {
+    if (!DB_) {
+        throw "SQLite connection is closed.";
+    }
+
+    printf("DELETE:   ");
+    char * errorMsg = NULL;
+
+    for (uint32_t i = 0; i < Num_; i++) {
+
+        uint32_t x = BASE_ADDR4 + i;
+        char * errorMsg = NULL;
+
+        char query[2000];
+        sprintf(query, "DELETE FROM lease4 WHERE addr=%d", x);
+        int result = sqlite3_exec(DB_, query, NULL /* no callback here*/, 0, &errorMsg);
+        if (result != SQLITE_OK) {
+            stringstream tmp;
+            tmp << "DELETE error:" << errorMsg;
+            failure(tmp.str().c_str());
+        }
+        printf(".");
+    }
+
+    printf("\n");
+}
+
+void SQLite_uBenchmark::printInfo() {
+    cout << "SQLite version is " << sqlite3_libversion()
+         << "sourceid version is " << sqlite3_sourceid() << endl;
+}
+
+
+
+int main(int argc, const char * argv[]) {
+
+    const char * filename = "sqlite.db";
+    uint32_t num = 10;
+
+    SQLite_uBenchmark bench(filename, num);
+
+    int result = bench.run();
+
+    return (result);
+}

+ 36 - 0
tests/tools/dhcp-ubench/sqlite_ubench.h

@@ -0,0 +1,36 @@
+// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <string>
+#include "benchmark.h"
+
+class SQLite_uBenchmark: public uBenchmark {
+public:
+    SQLite_uBenchmark(const std::string& filename,
+                      uint32_t num_iterations);
+
+    virtual void printInfo();
+    virtual void connect();
+    virtual void disconnect();
+    virtual void createLease4Test();
+    virtual void searchLease4Test();
+    virtual void updateLease4Test();
+    virtual void deleteLease4Test();
+
+protected:
+    void failure(const char* operation);
+
+    std::string Filename_;
+    sqlite3 *DB_;
+};