saving current changes

This commit is contained in:
2025-04-30 12:11:10 +01:00
parent 788aadfc9c
commit 4408efc5b8
38 changed files with 232842 additions and 40 deletions

View File

@@ -1,3 +1,3 @@
cc -g -Wall -o memaccesstest.out -mabi=purecap-benchmark -lpthread memaccesstest.c
cc -g -Wall -o loadmem.out -mabi=purecap-benchmark -lpthread loadmem.c
cc -g -Wall -o glibc-bench.out -mabi=purecap-benchmark -lpthread glibc-bench.c
cc -g -Wall -o memaccesstest.out -lpthread memaccesstest.c
cc -g -Wall -o loadmem.out -lpthread loadmem.c
cc -g -Wall -o glibc-bench.out -lpthread glibc-bench.c

View File

@@ -75,12 +75,12 @@ do_benchmark (malloc_args *args, char**arr)
// free half in fifo order
for (int i = 0; i < n/2; i++) {
free (arr[i]);
// free (arr[i]);
}
// and the other half in lifo order
for(int i = n-1; i >= n/2; i--) {
free(arr[i]);
// free(arr[i]);
}
}
@@ -135,7 +135,7 @@ bench (unsigned long size)
for (int i = 0; i < NUM_ALLOCS; i++)
do_benchmark (&tests[1][i], arr);
free (arr);
// free (arr);
/*
json_ctx_t json_ctx;

View File

@@ -1,2 +1,3 @@
sh build.sh
time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o glibc-regular-2.stat ./glibc-bench.out
# sh build.sh
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o glibc-cheri.stat ./glibc-bench.out
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o glibc-regular.stat ./glibc-bench.out

View File

@@ -25,7 +25,7 @@ bench (unsigned long n) {
// printf("Sleep 10 seconds......\n");
// sleep(10);
// printf("Free memory.\n");
free(ptr);
// free(ptr);
}
int main(){

View File

@@ -260,7 +260,7 @@ void * walk(void *param)
// printf("%d,%ld,%ld,%ld\n",data->thread_index,data->working_set_size, end-start, data->working_set_size/sizeof(struct l));
free(data);
// free(data);
return NULL;
}
@@ -315,7 +315,7 @@ int main(int argc,char **argv)
}
free(root);
// free(root);
}

View File

@@ -1,2 +1,3 @@
sh build.sh
time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o memaccesstest.stat ./memaccesstest.out
# sh build.sh
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o memaccesstest-cheri.stat ./memaccesstest.out
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o memaccesstest-regular.stat ./memaccesstest.out

View File

@@ -1,2 +1,3 @@
sh build.sh
time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o loadmem-regular.stat ./loadmem.out
# sh build.sh
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o loadmem-cheri.stat ./loadmem.out
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o loadmem-regular.stat ./loadmem.out

View File

@@ -3,8 +3,8 @@
// #include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
SimulationData grid_init_do_not_profile( Inputs in, int mype )
{
@@ -127,8 +127,8 @@ SimulationData grid_init_do_not_profile( Inputs in, int mype )
}
}
free(idx_low);
free(energy_high);
// free(idx_low);
// free(energy_high);
}
if( in.grid_type == HASH )

View File

@@ -7,8 +7,8 @@
#include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
int main(int argc, char* argv[] )
{

View File

@@ -64,7 +64,7 @@ LDFLAGS = -lm
# AML
CFLAGS += -g -Wall -mabi=purecap-benchmark -lpthread
CFLAGS += -g -Wall -lpthread
#===============================================================================
# Targets to Build

View File

@@ -7,8 +7,8 @@
// #include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
// num_nucs represents the number of nuclides that each material contains
int * load_num_nucs(long n_isotopes)

View File

@@ -3,8 +3,8 @@
// #include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
////////////////////////////////////////////////////////////////////////////////////
// BASELINE FUNCTIONS

View File

@@ -3,8 +3,8 @@
// #include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
int double_compare(const void * a, const void * b)
{

View File

@@ -3,8 +3,8 @@
// #include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
#ifdef MPI
#include<mpi.h>

View File

@@ -0,0 +1,2 @@
LD_PRELOAD=./libjemalloc.so pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o XSCHERI-alloc.txt ./XSBench -s small > XSCHERI-alloc-cheri-out.txt
LD_PRELOAD=./regularjemalloc.so pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o XSCHERI-regular.txt ./XSBench -s small > XSCHERI-alloc-out.txt

View File

@@ -40,7 +40,7 @@ PREPEND(barnes_sources . ${barnes_sources})
# turn off warnings..
message(STATUS "${CMAKE_C_COMPILER_ID}")
if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU")
set(FLAGS " -w -Wno-implicit-function-declaration -Wno-implicit-int -Wno-int-conversion -Wno-return-mismatch -Wno-incompatible-pointer-types -mabi=purecap-benchmark")
set(FLAGS " -w -Wno-implicit-function-declaration -Wno-implicit-int -Wno-int-conversion -Wno-return-mismatch -Wno-incompatible-pointer-types")
string(APPEND CMAKE_C_FLAGS ${FLAGS})
string(APPEND CMAKE_CXX_FLAGS ${FLAGS})
endif()

View File

@@ -79,8 +79,8 @@ Command line options:
#include "malloc.h"
#define malloc MALLOCCHERI
#define free FREECHERI
// #define malloc MALLOCCHERI
// #define free FREECHERI
string defv[] = { /* DEFAULT PARAMETER VALUES */
@@ -116,7 +116,7 @@ int argc;
string argv[];
{
INITREGULARALLOC(0);
// INITREGULARALLOC(0);
unsigned ProcessId = 0;
int c;

View File

@@ -1 +1,2 @@
time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o barnes-regular.txt ./barnes BARNES < input
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o barnes-cheri.txt ./barnes BARNES < input
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o barnes-regular.txt ./barnes BARNES < input

View File

@@ -5,7 +5,18 @@ sh build.sh
# time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-alloc-250000.txt ./kmeans-pthread.out -d 40 -c 100 -p 250000 -s 1000 > kmeans-bounds-regular-250000-out.txt
# time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-alloc-200000.txt ./kmeans-pthread.out -d 40 -c 100 -p 200000 -s 1000 > kmeans-bounds-regular-200000-out.txt
# time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-alloc-150000.txt ./kmeans-pthread.out -d 40 -c 100 -p 150000 -s 1000 > kmeans-bounds-regular-150000-out.txt
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-cheri-new-alloc-100000.txt ./kmeans-pthread.out -d 40 -c 100 -p 100000 -s 1000 > kmeans-bounds-cheri-new-100000-out.txt
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-new-alloc-100000.txt ./kmeans-pthread.out -d 40 -c 100 -p 100000 -s 1000 > kmeans-bounds-regular-new-100000-out.txt
# LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-cheri-new-alloc-100000.txt ./kmeans-pthread.out -d 40 -c 100 -p 100000 -s 1000 > kmeans-bounds-cheri-new-100000-out.txt
# LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-new-alloc-100000.txt ./kmeans-pthread.out -d 40 -c 100 -p 100000 -s 1000 > kmeans-bounds-regular-new-100000-out.txt
# time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-alloc-10000.txt ./kmeans-pthread.out -d 40 -c 100 -p 10000 -s 1000 > kmeans-bounds-regular-10000-out.txt
# time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-alloc-1000.txt ./kmeans-pthread.out -d 40 -c 100 -p 1000 -s 1000 > kmeans-bounds-regular-1000-out.txt
# time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-regular-alloc-1000.txt ./kmeans-pthread.out -d 40 -c 100 -p 1000 -s 1000 > kmeans-bounds-regular-1000-out.txt
# Run large iteration
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-cheri-new-alloc-alloc-350000.txt ./kmeans-pthread.out -d 40 -c 100 -p 350000 -s 1000 > kmeans-bounds-cheri-new-alloc-350000-out.txt
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-new-alloc-alloc-350000.txt ./kmeans-pthread.out -d 40 -c 100 -p 350000 -s 1000 > kmeans-bounds-new-alloc-350000-out.txt
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-cheri-new-alloc-alloc-400000.txt ./kmeans-pthread.out -d 40 -c 100 -p 400000 -s 1000 > kmeans-bounds-cheri-new-alloc-400000-out.txt
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-new-alloc-alloc-400000.txt ./kmeans-pthread.out -d 40 -c 100 -p 400000 -s 1000 > kmeans-bounds-new-alloc-40000-out.txt
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-cheri-new-alloc-alloc-500000.txt ./kmeans-pthread.out -d 40 -c 100 -p 500000 -s 1000 > kmeans-bounds-cheri-new-alloc-500000-out.txt
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o kmeans-new-alloc-alloc-500000.txt ./kmeans-pthread.out -d 40 -c 100 -p 500000 -s 1000 > kmeans-bounds-new-alloc-50000-out.txt

View File

@@ -1,2 +1,2 @@
cc -g -Wall -o benchmark.out -mabi=purecap-benchmark -lpthread benchmark.c
time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o benchmark-regular.txt ./benchmark.out > benchmark-regular-out.txt
cc -g -Wall -o benchmark.out -lpthread benchmark.c

View File

@@ -0,0 +1,2 @@
LD_PRELOAD=./libjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o benchmark-cheri.txt ./benchmark.out > benchmark-cheri-out.txt
LD_PRELOAD=./regularjemalloc.so time pmcstat -d -w 1 -p l1d_tlb_rd -p l2d_tlb_rd -p l1d_tlb_refill -p cpu_cycles -p dtlb_walk -p stall_backend -p ll_cache_miss_rd -o benchmark-regular.txt ./benchmark.out > benchmark-regular-out.txt

View File

@@ -0,0 +1,37 @@
version: 2
jobs:
build:
docker:
- image: ubuntu:16.04
working_directory: /usr/src/sqlite-bench
branches:
only:
- master
steps:
- run:
name: Install toolchains
command: |
apt-get update
apt-get install -y build-essential make git
apt-get clean
- checkout
- run:
name: Build
command: make
- run:
name: Show help
command: ./sqlite-bench --help
- run:
name: Benchmark fillseq
command: ./sqlite-bench --benchmarks=fillseq --num=1000
- run:
name: Benchmark fillrandom
command: ./sqlite-bench --benchmarks=fillrandom --num=1000
- run:
name: Benchmark readseq
command: ./sqlite-bench --benchmarks=readseq --num=1000
- run:
name: Benchmark readrandom
command: ./sqlite-bench --benchmarks=readrandom --num=1000

View File

@@ -0,0 +1,5 @@
*.o
sqlite-bench
*.db
*.db-shm
*.db-wal

View File

@@ -0,0 +1,15 @@
FROM ubuntu:16.04
MAINTAINER Akira Moroo <retrage01@gmail.com>
RUN apt-get update && \
apt-get install -y build-essential make git && \
apt-get clean
RUN cd /usr/src && git clone https://github.com/retrage/sqlite-bench.git
WORKDIR /usr/src/sqlite-bench
RUN make
ENV PATH /usr/src/sqlite-bench:$PATH
ENTRYPOINT ["sqlite-bench", "--raw=1"]
CMD ["--help"]

View File

@@ -0,0 +1,29 @@
BSD 3-Clause License
Copyright (c) 2018, Akira Moroo
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,26 @@
CFLAGS=-Wall -I. -O2 -DNDEBUG -std=c99
SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o)
HDRS=$(wildcard *.h)
TARGET=sqlite-bench
LDFLAGS=-lpthread -ldl -lm -static
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET) $(LDFLAGS)
%.o : %.c
$(CC) $(CFLAGS) -c $<
$(OBJS): $(HDRS)
bench: $(TARGET) clean-db
./$(TARGET)
clean:
rm -f $(TARGET) *.o
clean-db:
rm -f dbbench_sqlite3*
.PHONY: bench clean clean-db

View File

@@ -0,0 +1,50 @@
# SQLite3 Benchmark [![CircleCI](https://circleci.com/gh/ukontainer/sqlite-bench.svg?style=shield)](https://circleci.com/gh/ukontainer/sqlite-bench)
A SQLite3 benchmark tool.
Most of the code comes from [LevelDB](https://github.com/google/leveldb).
This is C version of [benchmarks/db_bench_sqlite3.cc](https://github.com/google/leveldb/blob/main/benchmarks/db_bench_sqlite3.cc).
## Building
SQLite3 is included in the repository.
```sh
$ make
```
## Usage
```
$ ./sqlite-bench --help
Usage: ./sqlite-bench [OPTION]...
SQLite3 benchmark tool
[OPTION]
--benchmarks=[BENCH] specify benchmark
--histogram={0,1} record histogram
--raw={0,1} output raw data
--compression_ratio=DOUBLE compression ratio
--use_existing_db={0,1} use existing database
--num=INT number of entries
--reads=INT number of reads
--value_size=INT value size
--no_transaction disable transaction
--page_size=INT page size
--num_pages=INT number of pages
--WAL_enabled={0,1} enable WAL
--db=PATH path to location databases are created
--help show this help
[BENCH]
fillseq write N values in sequential key order in async mode
fillseqsync write N/100 values in sequential key order in sync mode
fillseqbatch batch write N values in sequential key order in async mode
fillrandom write N values in random key order in async mode
fillrandsync write N/100 values in random key order in sync mode
fillrandbatch batch write N values in random key order in async mode
overwrite overwrite N values in random key order in async mode
fillrand100K write N/1000 100K values in random order in async mode
fillseq100K wirte N/1000 100K values in sequential order in async mode
readseq read N times sequentially
readrandom read N times in random order
readrand100K read N/1000 100K values in sequential order in async mode
```

View File

@@ -0,0 +1,139 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#ifndef BENCH_H_
#define BENCH_H_
#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include "sqlite3.h"
#define kNumBuckets 154
#define kNumData 1000000
typedef struct Histogram {
double min_;
double max_;
double num_;
double sum_;
double sum_squares_;
double buckets_[kNumBuckets];
} Histogram;
typedef struct Raw {
double *data_;
size_t data_size_;
int pos_;
} Raw;
typedef struct Random {
uint32_t seed_;
} Random;
typedef struct RandomGenerator {
char *data_;
size_t data_size_;
int pos_;
} RandomGenerator;
// Comma-separated list of operations to run in the specified order
// Actual benchmarks:
//
// fillseq -- write N values in sequential key order in async mode
// fillseqsync -- write N/100 values in sequential key order in sync mode
// fillseqbatch -- batch write N values in sequential key order in async mode
// fillrandom -- write N values in random key order in async mode
// fillrandsync -- write N/100 values in random key order in sync mode
// fillrandbatch -- batch write N values in sequential key order in async mode
// overwrite -- overwrite N values in random key order in async mode
// fillrand100K -- write N/1000 100K values in random order in async mode
// fillseq100K -- write N/1000 100K values in sequential order in async mode
// readseq -- read N times sequentially
// readrandom -- read N times in random order
// readrand100K -- read N/1000 100K values in sequential order in async mode
extern char* FLAGS_benchmarks;
// Number of key/values to place in database
extern int FLAGS_num;
// Number of read operations to do. If negative, do FLAGS_num reads.
extern int FLAGS_reads;
// Size of each value
extern int FLAGS_value_size;
// Print histogram of operation timings
extern bool FLAGS_histogram;
// Print raw data
extern bool FLAGS_raw;
// Arrange to generate values that shrink to this fraction of
// their original size after compression
extern double FLAGS_compression_ratio;
// Page size. Default 1 KB.
extern int FLAGS_page_size;
// Number of pages.
// Default cache size = FLAGS_page_size * FLAGS_num_pages = 4 MB.
extern int FLAGS_num_pages;
// If true, do not destroy the existing database. If you set this
// flag and also specify a benchmark that wants a fresh database, that
// benchmark will fail.
extern bool FLAGS_use_existing_db;
// If true, we allow batch writes to occur
extern bool FLAGS_transaction;
// If true, we enable Write-Ahead Logging
extern bool FLAGS_WAL_enabled;
// Use the db with the following name.
extern char* FLAGS_db;
/* benchmark.c */
void benchmark_init(void);
void benchmark_fini(void);
void benchmark_run(void);
void benchmark_open(void);
void benchmark_write(bool, int, int, int, int, int);
void benchmark_read(int, int);
void benchmark_read_sequential(void);
/* histogram.c */
void histogram_clear(Histogram*);
void histogram_add(Histogram*, double);
void histogram_merge(Histogram*, const Histogram*);
char* histogram_to_string(Histogram*);
/* Raw */
void raw_clear(Raw *);
void raw_add(Raw *, double);
char* raw_to_string(Raw *);
void raw_print(FILE *, Raw *);
/* random.c */
void rand_init(Random*, uint32_t);
uint32_t rand_next(Random*);
uint32_t rand_uniform(Random*, int);
void rand_gen_init(RandomGenerator*, double);
char* rand_gen_generate(RandomGenerator*, int);
/* util.c */
uint64_t now_micros(void);
bool starts_with(const char*, const char*);
char* trim_space(const char*);
#endif /* BENCH_H_ */

View File

@@ -0,0 +1,551 @@
// Copyright (c 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "bench.h"
enum Order {
SEQUENTIAL,
RANDOM
};
enum DBState {
FRESH,
EXISTING
};
sqlite3* db_;
int db_num_;
int num_;
int reads_;
double start_;
double last_op_finish_;
int64_t bytes_;
char* message_;
Histogram hist_;
Raw raw_;
RandomGenerator gen_;
Random rand_;
/* State kept for progress messages */
int done_;
int next_report_;
static void print_header(void);
static void print_warnings(void);
static void print_environment(void);
static void start(void);
static void stop(const char *name);
inline
static void exec_error_check(int status, char *err_msg) {
if (status != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_msg);
sqlite3_free(err_msg);
exit(1);
}
}
inline
static void step_error_check(int status) {
if (status != SQLITE_DONE) {
fprintf(stderr, "SQL step error: status = %d\n", status);
exit(1);
}
}
inline
static void error_check(int status) {
if (status != SQLITE_OK) {
fprintf(stderr, "sqlite3 error: status = %d\n", status);
exit(1);
}
}
inline
static void wal_checkpoint(sqlite3* db_) {
/* Flush all writes to disk */
if (FLAGS_WAL_enabled) {
sqlite3_wal_checkpoint_v2(db_, NULL, SQLITE_CHECKPOINT_FULL, NULL,
NULL);
}
}
static void print_header() {
const int kKeySize = 16;
print_environment();
fprintf(stderr, "Keys: %d bytes each\n", kKeySize);
fprintf(stderr, "Values: %d bytes each\n", FLAGS_value_size);
fprintf(stderr, "Entries: %d\n", num_);
fprintf(stderr, "RawSize: %.1f MB (estimated)\n",
(((int64_t)(kKeySize + FLAGS_value_size) * num_)
/ 1048576.0));
print_warnings();
fprintf(stderr, "------------------------------------------------\n");
}
static void print_warnings() {
#if defined(__GNUC__) && !defined(__OPTIMIZE__)
fprintf(stderr,
"WARNING: Optimization is disabled: benchmarks unnecessarily slow\n"
);
#endif
#ifndef NDEBUG
fprintf(stderr,
"WARNING: Assertions are enabled: benchmarks unnecessarily slow\n"
);
#endif
}
static void print_environment() {
fprintf(stderr, "SQLite: version %s\n", SQLITE_VERSION);
#if defined(__linux)
time_t now = time(NULL);
fprintf(stderr, "Date: %s", ctime(&now));
FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
if (cpuinfo != NULL) {
char line[1000];
int num_cpus = 0;
char* cpu_type = malloc(sizeof(char) * 1000);
char* cache_size = malloc(sizeof(char) * 1000);
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
char* sep = strchr(line, ':');
if (sep == NULL) {
continue;
}
char* key = calloc(sizeof(char), 1000);
char* val = calloc(sizeof(char), 1000);
strncpy(key, line, sep - 1 - line);
strcpy(val, sep + 1);
char* trimed_key = trim_space(key);
char* trimed_val = trim_space(val);
free(key);
free(val);
if (!strcmp(trimed_key, "model name")) {
++num_cpus;
strcpy(cpu_type, trimed_val);
} else if (!strcmp(trimed_key, "cache size")) {
strcpy(cache_size, trimed_val);
}
free(trimed_key);
free(trimed_val);
}
fclose(cpuinfo);
fprintf(stderr, "CPU: %d * %s\n", num_cpus, cpu_type);
fprintf(stderr, "CPUCache: %s\n", cache_size);
free(cpu_type);
free(cache_size);
}
#endif
}
static void start() {
start_ = now_micros() * 1e-6;
bytes_ = 0;
message_ = malloc(sizeof(char) * 10000);
strcpy(message_, "");
last_op_finish_ = start_;
histogram_clear(&hist_);
raw_clear(&raw_);
done_ = 0;
next_report_ = 100;
}
void finished_single_op() {
if (FLAGS_histogram || FLAGS_raw) {
double now = now_micros() * 1e-6;
double micros = (now - last_op_finish_) * 1e6;
if (FLAGS_histogram) {
histogram_add(&hist_, micros);
if (micros > 20000) {
fprintf(stderr, "long op: %.1f micros%30s\r", micros, "");
fflush(stderr);
}
}
if (FLAGS_raw) {
raw_add(&raw_, micros);
}
last_op_finish_ = now;
}
done_++;
if (done_ >= next_report_) {
if (next_report_ < 1000) next_report_ += 100;
else if (next_report_ < 5000) next_report_ += 500;
else if (next_report_ < 10000) next_report_ += 1000;
else if (next_report_ < 50000) next_report_ += 5000;
else if (next_report_ < 100000) next_report_ += 10000;
else if (next_report_ < 500000) next_report_ += 50000;
else next_report_ += 100000;
fprintf(stderr, "... finished %d ops%30s\r", done_, "");
fflush(stderr);
}
}
static void stop(const char* name) {
double finish = now_micros() * 1e-6;
if (done_ < 1) done_ = 1;
if (bytes_ > 0) {
char *rate = malloc(sizeof(char) * 100);;
snprintf(rate, strlen(rate), "%6.1f MB/s",
(bytes_ / 1048576.0) / (finish - start_));
if (message_ && !strcmp(message_, "")) {
message_ = strcat(strcat(rate, " "), message_);
} else {
message_ = rate;
}
}
fprintf(stderr, "%-12s : %11.3f micros/op;%s%s\n",
name,
(finish - start_) * 1e6 / done_,
(!message_ || !strcmp(message_, "") ? "" : " "),
(!message_) ? "" : message_);
if (FLAGS_raw) {
raw_print(stdout, &raw_);
}
if (FLAGS_histogram) {
fprintf(stderr, "Microseconds per op:\n%s\n",
histogram_to_string(&hist_));
}
fflush(stdout);
fflush(stderr);
}
void benchmark_init() {
db_ = NULL;
db_num_ = 0;
num_ = FLAGS_num;
reads_ = FLAGS_reads < 0 ? FLAGS_num : FLAGS_reads;
bytes_ = 0;
rand_gen_init(&gen_, FLAGS_compression_ratio);
rand_init(&rand_, 301);;
struct dirent* ep;
DIR* test_dir = opendir(FLAGS_db);
if (!FLAGS_use_existing_db) {
while ((ep = readdir(test_dir)) != NULL) {
if (starts_with(ep->d_name, "dbbench_sqlite3")) {
char file_name[1000];
strcpy(file_name, FLAGS_db);
strcat(file_name, ep->d_name);
remove(file_name);
}
}
}
closedir(test_dir);
}
void benchmark_fini() {
int status = sqlite3_close(db_);
error_check(status);
}
void benchmark_run() {
print_header();
benchmark_open();
char* benchmarks = FLAGS_benchmarks;
while (benchmarks != NULL) {
char* sep = strchr(benchmarks, ',');
char* name;
if (sep == NULL) {
name = benchmarks;
benchmarks = NULL;
} else {
name = calloc(sizeof(char), (sep - benchmarks + 1));
strncpy(name, benchmarks, sep - benchmarks);
benchmarks = sep + 1;
}
bytes_ = 0;
start();
bool known = true;
bool write_sync = false;
if (!strcmp(name, "fillseq")) {
benchmark_write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillseqbatch")) {
benchmark_write(write_sync, SEQUENTIAL, FRESH, num_, FLAGS_value_size, 1000);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillrandom")) {
benchmark_write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillrandbatch")) {
benchmark_write(write_sync, RANDOM, FRESH, num_, FLAGS_value_size, 1000);
wal_checkpoint(db_);
} else if (!strcmp(name, "overwrite")) {
benchmark_write(write_sync, RANDOM, EXISTING, num_, FLAGS_value_size, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "overwritebatch")) {
benchmark_write(write_sync, RANDOM, EXISTING, num_, FLAGS_value_size, 1000);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillrandsync")) {
write_sync = true;
benchmark_write(write_sync, RANDOM, FRESH, num_ / 100, FLAGS_value_size, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillseqsync")) {
write_sync = true;
benchmark_write(write_sync, SEQUENTIAL, FRESH, num_ / 100, FLAGS_value_size, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillrand100K")) {
benchmark_write(write_sync, RANDOM, FRESH, num_ / 1000, 100 * 1000, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "fillseq100K")) {
benchmark_write(write_sync, SEQUENTIAL, FRESH, num_ / 1000, 100 * 1000, 1);
wal_checkpoint(db_);
} else if (!strcmp(name, "readseq")) {
benchmark_read(SEQUENTIAL, 1);
} else if (!strcmp(name, "readrandom")) {
benchmark_read(RANDOM, 1);
} else if (!strcmp(name, "readrand100K")) {
int n = reads_;
reads_ /= 1000;
benchmark_read(RANDOM, 1);
reads_ = n;
} else {
known = false;
if (strcmp(name, "")) {
fprintf(stderr, "unknown benchmark '%s'\n", name);
}
}
if (known) {
stop(name);
}
}
}
void benchmark_open() {
assert(db_ == NULL);
int status;
char file_name[100];
char* err_msg = NULL;
db_num_++;
/* Open database */
char *tmp_dir = FLAGS_db;
snprintf(file_name, sizeof(file_name),
"%sdbbench_sqlite3-%d.db",
tmp_dir,
db_num_);
status = sqlite3_open(file_name, &db_);
if (status) {
fprintf(stderr, "open error: %s\n", sqlite3_errmsg(db_));
exit(1);
}
/* Change SQLite cache size */
char cache_size[100];
snprintf(cache_size, sizeof(cache_size), "PRAGMA cache_size = %d",
FLAGS_num_pages);
status = sqlite3_exec(db_, cache_size, NULL, NULL, &err_msg);
exec_error_check(status, err_msg);
/* FLAGS_page_size is defaulted to 1024 */
if (FLAGS_page_size != 1024) {
char page_size[100];
snprintf(page_size, sizeof(page_size), "PRAGMA page_size = %d",
FLAGS_page_size);
status = sqlite3_exec(db_, page_size, NULL, NULL, &err_msg);
exec_error_check(status, err_msg);
}
/* Change journal mode to WAL if WAL enabled flag is on */
if (FLAGS_WAL_enabled) {
char* WAL_stmt = "PRAGMA journal_mode = WAL";
/* Default cache size is a combined 4 MB */
char* WAL_checkpoint = "PRAGMA wal_autocheckpoint = 4096";
status = sqlite3_exec(db_, WAL_stmt, NULL, NULL, &err_msg);
exec_error_check(status, err_msg);
status = sqlite3_exec(db_, WAL_checkpoint, NULL, NULL, &err_msg);
exec_error_check(status, err_msg);
}
/* Change locking mode to exclusive and create tables/index for database */
char* locking_stmt = "PRAGMA locking_mode = EXCLUSIVE";
char* create_stmt =
"CREATE TABLE test (key blob, value blob, PRIMARY KEY (key))";
char* stmt_array[] = { locking_stmt, create_stmt, NULL };
int stmt_array_length = sizeof(stmt_array) / sizeof(char*);
for (int i = 0; i < stmt_array_length; i++) {
status = sqlite3_exec(db_, stmt_array[i], NULL, NULL, &err_msg);
exec_error_check(status, err_msg);
}
}
void benchmark_write(bool write_sync, int order, int state,
int num_entries, int value_size, int entries_per_batch) {
/* Create new database if state == FRESH */
if (state == FRESH) {
if (FLAGS_use_existing_db) {
message_ = malloc(sizeof(char) * 100);
strcpy(message_, "skipping (--use_existing_db is true)");
return;
}
sqlite3_close(db_);
db_ = NULL;
benchmark_open();
start();
}
if (num_entries != num_) {
char* msg = malloc(sizeof(char) * 100);
snprintf(msg, 100, "(%d ops)", num_entries);
message_ = msg;
}
char* err_msg = NULL;
int status;
sqlite3_stmt *replace_stmt, *begin_trans_stmt, *end_trans_stmt;
char* replace_str = "REPLACE INTO test (key, value) VALUES (?, ?)";
char* begin_trans_str = "BEGIN TRANSACTION";
char* end_trans_str = "END TRANSACTION";
/* Check for synchronous flag in options */
char* sync_stmt = (write_sync) ? "PRAGMA synchronous = FULL" :
"PRAGMA synchronous = OFF";
status = sqlite3_exec(db_, sync_stmt, NULL, NULL, &err_msg);
exec_error_check(status, err_msg);
/* Preparing sqlite3 statements */
status = sqlite3_prepare_v2(db_, replace_str, -1,
&replace_stmt, NULL);
error_check(status);
status = sqlite3_prepare_v2(db_, begin_trans_str, -1,
&begin_trans_stmt, NULL);
error_check(status);
status = sqlite3_prepare_v2(db_, end_trans_str, -1,
&end_trans_stmt, NULL);
error_check(status);
bool transaction = (entries_per_batch > 1);
for (int i = 0; i < num_entries; i += entries_per_batch) {
/* Begin write transaction */
if (FLAGS_transaction && transaction) {
status = sqlite3_step(begin_trans_stmt);
step_error_check(status);
status = sqlite3_reset(begin_trans_stmt);
error_check(status);
}
/* Create and execute SQL statements */
for (int j = 0; j < entries_per_batch; j++) {
const char* value = rand_gen_generate(&gen_, value_size);
/* Create values for key-value pair */
const int k = (order == SEQUENTIAL) ? i + j :
(rand_next(&rand_) % num_entries);
char key[100];
snprintf(key, sizeof(key), "%016d", k);
/* Bind KV values into replace_stmt */
status = sqlite3_bind_blob(replace_stmt, 1, key, 16, SQLITE_STATIC);
error_check(status);
status = sqlite3_bind_blob(replace_stmt, 2, value,
value_size, SQLITE_STATIC);
error_check(status);
/* Execute replace_stmt */
bytes_ += value_size + strlen(key);
status = sqlite3_step(replace_stmt);
step_error_check(status);
/* Reset SQLite statement for another use */
status = sqlite3_clear_bindings(replace_stmt);
error_check(status);
status = sqlite3_reset(replace_stmt);
error_check(status);
finished_single_op();
}
/* End write transaction */
if (FLAGS_transaction && transaction) {
status = sqlite3_step(end_trans_stmt);
step_error_check(status);
status = sqlite3_reset(end_trans_stmt);
error_check(status);
}
}
status = sqlite3_finalize(replace_stmt);
error_check(status);
status = sqlite3_finalize(begin_trans_stmt);
error_check(status);
status = sqlite3_finalize(end_trans_stmt);
error_check(status);
}
void benchmark_read(int order, int entries_per_batch) {
int status;
sqlite3_stmt *read_stmt, *begin_trans_stmt, *end_trans_stmt;
char *read_str = "SELECT * FROM test WHERE key = ?";
char *begin_trans_str = "BEGIN TRANSACTION";
char *end_trans_str = "END TRANSACTION";
/* Preparing sqlite3 statements */
status = sqlite3_prepare_v2(db_, begin_trans_str, -1,
&begin_trans_stmt, NULL);
error_check(status);
status = sqlite3_prepare_v2(db_, end_trans_str, -1,
&end_trans_stmt, NULL);
error_check(status);
status = sqlite3_prepare_v2(db_, read_str, -1,
&read_stmt, NULL);
error_check(status);
bool transaction = (entries_per_batch > 1);
for (int i = 0; i < reads_; i += entries_per_batch) {
/* Begin read transaction */
if (FLAGS_transaction && transaction) {
status = sqlite3_step(begin_trans_stmt);
step_error_check(status);
status = sqlite3_reset(begin_trans_stmt);
error_check(status);
}
/* Create and execute SQL statements */
for (int j = 0; j < entries_per_batch; j++) {
/* Create key value */
char key[100];
int k = (order == SEQUENTIAL) ? i + j : (rand_next(&rand_) % reads_);
snprintf(key, sizeof(key), "%016d", k);
/* Bind key value into read_stmt */
status = sqlite3_bind_blob(read_stmt, 1, key, 16, SQLITE_STATIC);
error_check(status);
/* Execute read statement */
while ((status = sqlite3_step(read_stmt)) == SQLITE_ROW) {}
step_error_check(status);
/* Reset SQLite statement for another use */
status = sqlite3_clear_bindings(read_stmt);
error_check(status);
status = sqlite3_reset(read_stmt);
error_check(status);
finished_single_op();
}
/* End read transaction */
if (FLAGS_transaction && transaction) {
status = sqlite3_step(end_trans_stmt);
step_error_check(status);
status = sqlite3_reset(end_trans_stmt);
error_check(status);
}
}
status = sqlite3_finalize(read_stmt);
error_check(status);
status = sqlite3_finalize(begin_trans_stmt);
error_check(status);
status = sqlite3_finalize(end_trans_stmt);
error_check(status);
}

View File

@@ -0,0 +1,157 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "bench.h"
static double median(Histogram*);
static double percentile(Histogram*, double);
static double average(Histogram*);
static double standard_deviation(Histogram*);
const static double bucket_limit[kNumBuckets] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 20, 25, 30, 35, 40, 45,
50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300, 350, 400, 450,
500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000, 2500, 3000,
3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000,
16000, 18000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 60000,
70000, 80000, 90000, 100000, 120000, 140000, 160000, 180000, 200000,
250000, 300000, 350000, 400000, 450000, 500000, 600000, 700000, 800000,
900000, 1000000, 1200000, 1400000, 1600000, 1800000, 2000000, 2500000,
3000000, 3500000, 4000000, 4500000, 5000000, 6000000, 7000000, 8000000,
9000000, 10000000, 12000000, 14000000, 16000000, 18000000, 20000000,
25000000, 30000000, 35000000, 40000000, 45000000, 50000000, 60000000,
70000000, 80000000, 90000000, 100000000, 120000000, 140000000, 160000000,
180000000, 200000000, 250000000, 300000000, 350000000, 400000000,
450000000, 500000000, 600000000, 700000000, 800000000, 900000000,
1000000000, 1200000000, 1400000000, 1600000000, 1800000000, 2000000000,
2500000000.0, 3000000000.0, 3500000000.0, 4000000000.0, 4500000000.0,
5000000000.0, 6000000000.0, 7000000000.0, 8000000000.0, 9000000000.0,
1e200,
};
static double median(Histogram* hist_) {
return percentile(hist_, 50.0);
}
static double percentile(Histogram* hist_, double p) {
double threshold = hist_->num_ * (p / 100.0);
double sum = 0;
for (int b = 0; b < kNumBuckets; b++) {
sum += hist_->buckets_[b];
if (sum >= threshold) {
/* Scale linearly within this bucket */
double left_point = (b == 0) ? 0 : bucket_limit[b - 1];
double right_point = bucket_limit[b];
double left_sum = sum - hist_->buckets_[b];
double right_sum = sum;
double pos = (threshold - left_sum) / (right_sum - left_sum);
double r = left_point + (right_point - left_point) * pos;
if (r < hist_->min_) r = hist_->min_;
if (r > hist_->max_) r = hist_->max_;
return r;
}
}
return hist_->max_;
}
static double average(Histogram* hist_) {
if (hist_->num_ == 0.0) return 0;
return hist_->sum_ / hist_->num_;
}
static double standard_deviation(Histogram* hist_) {
if (hist_->num_ == 0.0) return 0;
double variance = (hist_->sum_squares_ * hist_->num_ - hist_->sum_ * hist_->sum_) / (hist_->num_ * hist_->num_);
return sqrt(variance);
}
void histogram_clear(Histogram* hist_) {
hist_->min_ = bucket_limit[kNumBuckets - 1];
hist_->max_ = 0;
hist_->num_ = 0;
hist_->sum_ = 0;
hist_->sum_squares_ = 0;
for (int i = 0; i < kNumBuckets; i++) {
hist_->buckets_[i] = 0;
}
}
void histogram_add(Histogram* hist_, double value) {
int b = 0;
while (b < kNumBuckets - 1 && bucket_limit[b] <= value) {
b++;
}
hist_->buckets_[b] += 1.0;
if (hist_->min_ > value) hist_->min_ = value;
if (hist_->max_ < value) hist_->max_ = value;
hist_->num_++;
hist_->sum_ += value;
hist_->sum_squares_ += (value * value);
}
void histogram_merge(Histogram* hist_, const Histogram* other_) {
if (other_->min_ < hist_->min_) hist_->min_ = other_->min_;
if (other_->max_ > hist_->max_) hist_->max_ = other_->max_;
hist_->num_ += other_->num_;
hist_->sum_ += other_->sum_;
hist_->sum_squares_ += other_->sum_squares_;
for (int b = 0; b < kNumBuckets; b++) {
hist_->buckets_[b] += other_->buckets_[b];
}
}
char* histogram_to_string(Histogram* hist_) {
size_t r_size = 1024;
char* r = malloc(sizeof(char) * 1024);
strcpy(r, "");
char buf[200];
snprintf(buf, sizeof(buf),
"Count: %.0f Average: %.4f StdDiv: %.2f\n",
hist_->num_, average(hist_), standard_deviation(hist_));
if (r_size < strlen(r) + strlen(buf)) {
r = realloc(r, r_size * 2);
r_size *= 2;
}
strcat(r, buf);
snprintf(buf, sizeof(buf),
"Min: %.4f Median: %.4f Max: %.4f\n",
(hist_->num_ == 0.0 ? 0.0 : hist_->min_),
median(hist_), hist_->max_);
if (r_size < strlen(r) + strlen(buf)) {
r = realloc(r, r_size * 2);
r_size *= 2;
}
strcat(r, buf);
if (r_size < strlen(r) + strlen(buf)) {
r = realloc(r, r_size * 2);
r_size *= 2;
}
strcat(r, "------------------------------------------------------\n");
const double mult = 100.0 / hist_->num_;
double sum = 0;
for (int b = 0; b < kNumBuckets; b++) {
if (hist_->buckets_[b] <= 0.0) continue;
sum += hist_->buckets_[b];
snprintf(buf, sizeof(buf),
"[ %7.0f, %7.0f ) %7.0f %7.3f%% %7.3f%%",
((b == 0) ? 0.0 : bucket_limit[b - 1]),
bucket_limit[b],
hist_->buckets_[b],
mult * hist_->buckets_[b],
mult * sum);
if (r_size < strlen(r) + strlen(buf)) {
r = realloc(r, r_size * 2);
r_size *= 2;
}
strcat(r, buf);
/* Add hash marks based on percentage; 20 marks for 100%. */
int marks = (int)(20 * (hist_->buckets_[b] / hist_->num_) + 0.5);
if (r_size < strlen(r) + marks + 1) {
r = realloc(r, r_size * 2);
r_size *= 2;
}
for (int i = 0; i < marks; i++)
strcat(r, "#");
strcat(r, "\n");
}
return r;
}

View File

@@ -0,0 +1,203 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "bench.h"
// Comma-separated list of operations to run in the specified order
// Actual benchmarks:
//
// fillseq -- write N values in sequential key order in async mode
// fillseqsync -- write N/100 values in sequential key order in sync mode
// fillseqbatch -- batch write N values in sequential key order in async mode
// fillrandom -- write N values in random key order in async mode
// fillrandsync -- write N/100 values in random key order in sync mode
// fillrandbatch -- batch write N values in sequential key order in async mode
// overwrite -- overwrite N values in random key order in async mode
// fillrand100K -- write N/1000 100K values in random order in async mode
// fillseq100K -- write N/1000 100K values in sequential order in async mode
// readseq -- read N times sequentially
// readrandom -- read N times in random order
// readrand100K -- read N/1000 100K values in sequential order in async mode
char* FLAGS_benchmarks;
// Number of key/values to place in database
int FLAGS_num;
// Number of read operations to do. If negative, do FLAGS_num reads.
int FLAGS_reads;
// Size of each value
int FLAGS_value_size;
// Print histogram of operation timings
bool FLAGS_histogram;
// Print raw data
bool FLAGS_raw;
// Arrange to generate values that shrink to this fraction of
// their original size after compression
double FLAGS_compression_ratio;
// Page size. Default 1 KB.
int FLAGS_page_size;
// Number of pages.
// Default cache size = FLAGS_page_size * FLAGS_num_pages = 4 MB.
int FLAGS_num_pages;
// If true, do not destroy the existing database. If you set this
// flag and also specify a benchmark that wants a fresh database, that
// benchmark will fail.
bool FLAGS_use_existing_db;
// If true, we allow batch writes to occur
bool FLAGS_transaction;
// If true, we enable Write-Ahead Logging
bool FLAGS_WAL_enabled;
// Use the db with the following name.
char* FLAGS_db;
void init() {
// Comma-separated list of operations to run in the specified order
// Actual benchmarks:
//
// fillseq -- write N values in sequential key order in async mode
// fillseqsync -- write N/100 values in sequential key order in sync mode
// fillseqbatch -- batch write N values in sequential key order in async mode
// fillrandom -- write N values in random key order in async mode
// fillrandsync -- write N/100 values in random key order in sync mode
// fillrandbatch -- batch write N values in sequential key order in async mode
// overwrite -- overwrite N values in random key order in async mode
// fillrand100K -- write N/1000 100K values in random order in async mode
// fillseq100K -- write N/1000 100K values in sequential order in async mode
// readseq -- read N times sequentially
// readrandom -- read N times in random order
// readrand100K -- read N/1000 100K values in sequential order in async mode
FLAGS_benchmarks =
"fillseq,"
"fillseqsync,"
"fillseqbatch,"
"fillrandom,"
"fillrandsync,"
"fillrandbatch,"
"overwrite,"
"overwritebatch,"
"readrandom,"
"readseq,"
"fillrand100K,"
"fillseq100K,"
"readseq,"
"readrand100K,"
;
FLAGS_num = 1000000;
FLAGS_reads = -1;
FLAGS_value_size = 100;
FLAGS_histogram = false;
FLAGS_raw = false,
FLAGS_compression_ratio = 0.5;
FLAGS_page_size = 1024;
FLAGS_num_pages = 4096;
FLAGS_use_existing_db = false;
FLAGS_transaction = true;
FLAGS_WAL_enabled = true;
FLAGS_db = NULL;
}
void print_usage(const char* argv0) {
fprintf(stderr, "Usage: %s [OPTION]...\n", argv0);
fprintf(stderr, "SQLite3 benchmark tool\n");
fprintf(stderr, "[OPTION]\n");
fprintf(stderr, " --benchmarks=[BENCH]\t\tspecify benchmark\n");
fprintf(stderr, " --histogram={0,1}\t\trecord histogram\n");
fprintf(stderr, " --raw={0,1}\t\t\toutput raw data\n");
fprintf(stderr, " --compression_ratio=DOUBLE\tcompression ratio\n");
fprintf(stderr, " --use_existing_db={0,1}\tuse existing database\n");
fprintf(stderr, " --num=INT\t\t\tnumber of entries\n");
fprintf(stderr, " --reads=INT\t\t\tnumber of reads\n");
fprintf(stderr, " --value_size=INT\t\tvalue size\n");
fprintf(stderr, " --no_transaction\t\tdisable transaction\n");
fprintf(stderr, " --page_size=INT\t\tpage size\n");
fprintf(stderr, " --num_pages=INT\t\tnumber of pages\n");
fprintf(stderr, " --WAL_enabled={0,1}\t\tenable WAL\n");
fprintf(stderr, " --db=PATH\t\t\tpath to location databases are created\n");
fprintf(stderr, " --help\t\t\tshow this help\n");
fprintf(stderr, "\n");
fprintf(stderr, "[BENCH]\n");
fprintf(stderr, " fillseq\twrite N values in sequential key order in async mode\n");
fprintf(stderr, " fillseqsync\twrite N/100 values in sequential key order in sync mode\n");
fprintf(stderr, " fillseqbatch\tbatch write N values in sequential key order in async mode\n");
fprintf(stderr, " fillrandom\twrite N values in random key order in async mode\n");
fprintf(stderr, " fillrandsync\twrite N/100 values in random key order in sync mode\n");
fprintf(stderr, " fillrandbatch\tbatch write N values in random key order in async mode\n");
fprintf(stderr, " overwrite\toverwrite N values in random key order in async mode\n");
fprintf(stderr, " fillrand100K\twrite N/1000 100K values in random order in async mode\n");
fprintf(stderr, " fillseq100K\twirte N/1000 100K values in sequential order in async mode\n");
fprintf(stderr, " readseq\tread N times sequentially\n");
fprintf(stderr, " readrandom\tread N times in random order\n");
fprintf(stderr, " readrand100K\tread N/1000 100K values in sequential order in async mode\n");
}
int main(int argc, char** argv) {
init();
char* default_db_path = malloc(sizeof(char) * 1024);
strcpy(default_db_path, "./");
for (int i = 1; i < argc; i++) {
double d;
int n;
char junk;
if (starts_with(argv[i], "--benchmarks=")) {
FLAGS_benchmarks = argv[i] + strlen("--benchmarks=");
} else if (sscanf(argv[i], "--histogram=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_histogram = n;
} else if (sscanf(argv[i], "--raw=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_raw = n;
} else if (sscanf(argv[i], "--compression_ratio=%lf%c", &d, &junk) == 1) {
FLAGS_compression_ratio = d;
} else if (sscanf(argv[i], "--use_existing_db=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_use_existing_db = n;
} else if (sscanf(argv[i], "--num=%d%c", &n, &junk) == 1) {
FLAGS_num = n;
} else if (sscanf(argv[i], "--reads=%d%c", &n, &junk) == 1) {
FLAGS_reads = n;
} else if (sscanf(argv[i], "--value_size=%d%c", &n, &junk) == 1) {
FLAGS_value_size = n;
} else if (!strcmp(argv[i], "--no_transaction")) {
FLAGS_transaction = false;
} else if (sscanf(argv[i], "--page_size=%d%c", &n, &junk) == 1) {
FLAGS_page_size = n;
} else if (sscanf(argv[i], "--num_pages=%d%c", &n, &junk) == 1) {
FLAGS_num_pages = n;
} else if (sscanf(argv[i], "--WAL_enabled=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
FLAGS_WAL_enabled = n;
} else if (strncmp(argv[i], "--db=", 5) == 0) {
FLAGS_db = argv[i] + 5;
} else if (!strcmp(argv[i], "--help")) {
print_usage(argv[0]);
exit(0);
} else {
fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
exit(1);
}
}
/* Choose a location for the test database if none given with --db=<path> */
if (FLAGS_db == NULL)
FLAGS_db = default_db_path;
benchmark_init();
benchmark_run();
benchmark_fini();
return 0;
}

View File

@@ -0,0 +1,98 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "bench.h"
static char *random_string(Random*, int);
static char *compressible_string(Random*, double, size_t);
/*
* https://github.com/google/leveldb/blob/master/util/testutil.cc
*/
static char *random_string(Random* rnd, int len) {
char* dst = malloc(sizeof(char) * (size_t)(len + 1));
for (int i = 0; i < len; i++) {
dst[i] = (char)(' ' + rand_uniform(rnd, 95));
}
dst[len] = '\0';
return dst;
}
static char *compressible_string(Random* rnd, double compressed_fraction,
size_t len) {
int raw = (int)(len * compressed_fraction);
if (raw < 1) raw = 1;
char* raw_data = random_string(rnd, raw);
size_t raw_data_len = strlen(raw_data);
int pos = 0;
char* dst = malloc(sizeof(char) * (len + 1));
dst[0] = '\0';
while (pos < len) {
strcat(dst, raw_data);
pos += raw_data_len;
}
return dst;
}
/*
* https://github.com/google/leveldb/blob/master/util/random.h
*/
void rand_init(Random* rand_, uint32_t s) {
rand_->seed_ = s & 0x7fffffffu;
/* Avoid bad seeds. */
if (rand_->seed_ == 0 || rand_->seed_ == 2147483647L) {
rand_->seed_ = 1;
}
}
uint32_t rand_next(Random* rand_) {
static const uint32_t M = 2147483647L;
static const uint64_t A = 16807;
uint64_t product = rand_->seed_ * A;
rand_->seed_ = (uint32_t)((product >> 31) + (product & M));
if (rand_->seed_ > M) {
rand_->seed_ -= M;
}
return rand_->seed_;
}
uint32_t rand_uniform(Random* rand_, int n) { return rand_next(rand_) % n; }
void rand_gen_init(RandomGenerator* gen_, double compression_ratio) {
Random rnd;
char* piece;
gen_->data_ = malloc(sizeof(char) * 1048576);
gen_->data_size_ = 0;
gen_->pos_ = 0;
(gen_->data_)[0] = '\0';
rand_init(&rnd, 301);
while (gen_->data_size_ < 1048576) {
piece = compressible_string(&rnd, compression_ratio, 100);
strcat(gen_->data_, piece);
gen_->data_size_ += strlen(piece);
}
free(piece);
}
char* rand_gen_generate(RandomGenerator* gen_, int len) {
if (gen_->pos_ + len > gen_->data_size_) {
gen_->pos_ = 0;
assert(len < gen_->data_size_);
}
gen_->pos_ += len;
char* substr = malloc(sizeof(char) * (len + 1));
strncpy(substr, (gen_->data_) + gen_->pos_ - len, len);
return substr;
}

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "bench.h"
static void raw_calloc(Raw *raw_) {
raw_->data_size_ = kNumData;
raw_->data_ = calloc(sizeof(double), raw_->data_size_);
raw_->pos_ = 0;
}
static void raw_realloc(Raw *raw_) {
raw_->data_size_ *= 2;
raw_->data_ = realloc(raw_->data_, sizeof(double) * raw_->data_size_);
if (!raw_->data_) {
fprintf(stderr, "realloc failed\n");
exit(1);
}
}
void raw_clear(Raw *raw_) {
if (raw_->data_)
free(raw_->data_);
raw_calloc(raw_);
}
void raw_add(Raw *raw_, double value) {
if (!raw_->data_)
raw_calloc(raw_);
if (raw_->data_size_ < raw_->pos_ + 1)
raw_realloc(raw_);
raw_->data_[raw_->pos_] = value;
raw_->pos_++;
}
char* raw_to_string(Raw *raw_) {
if (!raw_->data_)
raw_calloc(raw_);
size_t r_size = 1024;
char *r = malloc(sizeof(char) * r_size);
strcpy(r, "");
char buf[200];
for (int i = 0; i < raw_->pos_; i++) {
snprintf(buf, sizeof(buf), "%.4f\n", raw_->data_[i]);
if (r_size < strlen(r) + strlen(buf)) {
r = realloc(r, r_size * 2);
r_size *= 2;
}
strcat(r, buf);
}
return r;
}
void raw_print(FILE *stream, Raw *raw_) {
if (!raw_->data_)
raw_calloc(raw_);
fprintf(stream, "num,time\n");
for (int i = 0; i < raw_->pos_; i++)
fprintf(stream, "%d,%.4f\n", i, raw_->data_[i]);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,623 @@
/*
** 2006 June 7
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the SQLite interface for use by
** shared libraries that want to be imported as extensions into
** an SQLite instance. Shared libraries that intend to be loaded
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
*/
#ifndef SQLITE3EXT_H
#define SQLITE3EXT_H
#include "sqlite3.h"
/*
** The following structure holds pointers to all of the SQLite API
** routines.
**
** WARNING: In order to maintain backwards compatibility, add new
** interfaces to the end of this structure only. If you insert new
** interfaces in the middle of this structure, then older different
** versions of SQLite will not be able to load each other's shared
** libraries!
*/
struct sqlite3_api_routines {
void * (*aggregate_context)(sqlite3_context*,int nBytes);
int (*aggregate_count)(sqlite3_context*);
int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
int (*bind_double)(sqlite3_stmt*,int,double);
int (*bind_int)(sqlite3_stmt*,int,int);
int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
int (*bind_null)(sqlite3_stmt*,int);
int (*bind_parameter_count)(sqlite3_stmt*);
int (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
const char * (*bind_parameter_name)(sqlite3_stmt*,int);
int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
int (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
int (*busy_timeout)(sqlite3*,int ms);
int (*changes)(sqlite3*);
int (*close)(sqlite3*);
int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const char*));
int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
int eTextRep,const void*));
const void * (*column_blob)(sqlite3_stmt*,int iCol);
int (*column_bytes)(sqlite3_stmt*,int iCol);
int (*column_bytes16)(sqlite3_stmt*,int iCol);
int (*column_count)(sqlite3_stmt*pStmt);
const char * (*column_database_name)(sqlite3_stmt*,int);
const void * (*column_database_name16)(sqlite3_stmt*,int);
const char * (*column_decltype)(sqlite3_stmt*,int i);
const void * (*column_decltype16)(sqlite3_stmt*,int);
double (*column_double)(sqlite3_stmt*,int iCol);
int (*column_int)(sqlite3_stmt*,int iCol);
sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol);
const char * (*column_name)(sqlite3_stmt*,int);
const void * (*column_name16)(sqlite3_stmt*,int);
const char * (*column_origin_name)(sqlite3_stmt*,int);
const void * (*column_origin_name16)(sqlite3_stmt*,int);
const char * (*column_table_name)(sqlite3_stmt*,int);
const void * (*column_table_name16)(sqlite3_stmt*,int);
const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
const void * (*column_text16)(sqlite3_stmt*,int iCol);
int (*column_type)(sqlite3_stmt*,int iCol);
sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
int (*complete)(const char*sql);
int (*complete16)(const void*sql);
int (*create_collation)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_collation16)(sqlite3*,const void*,int,void*,
int(*)(void*,int,const void*,int,const void*));
int (*create_function)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_function16)(sqlite3*,const void*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*));
int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
int (*data_count)(sqlite3_stmt*pStmt);
sqlite3 * (*db_handle)(sqlite3_stmt*);
int (*declare_vtab)(sqlite3*,const char*);
int (*enable_shared_cache)(int);
int (*errcode)(sqlite3*db);
const char * (*errmsg)(sqlite3*);
const void * (*errmsg16)(sqlite3*);
int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
int (*expired)(sqlite3_stmt*);
int (*finalize)(sqlite3_stmt*pStmt);
void (*free)(void*);
void (*free_table)(char**result);
int (*get_autocommit)(sqlite3*);
void * (*get_auxdata)(sqlite3_context*,int);
int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
int (*global_recover)(void);
void (*interruptx)(sqlite3*);
sqlite_int64 (*last_insert_rowid)(sqlite3*);
const char * (*libversion)(void);
int (*libversion_number)(void);
void *(*malloc)(int);
char * (*mprintf)(const char*,...);
int (*open)(const char*,sqlite3**);
int (*open16)(const void*,sqlite3**);
int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
void (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
void *(*realloc)(void*,int);
int (*reset)(sqlite3_stmt*pStmt);
void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_double)(sqlite3_context*,double);
void (*result_error)(sqlite3_context*,const char*,int);
void (*result_error16)(sqlite3_context*,const void*,int);
void (*result_int)(sqlite3_context*,int);
void (*result_int64)(sqlite3_context*,sqlite_int64);
void (*result_null)(sqlite3_context*);
void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
void (*result_value)(sqlite3_context*,sqlite3_value*);
void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
void (*thread_cleanup)(void);
int (*total_changes)(sqlite3*);
void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
sqlite_int64),void*);
void * (*user_data)(sqlite3_context*);
const void * (*value_blob)(sqlite3_value*);
int (*value_bytes)(sqlite3_value*);
int (*value_bytes16)(sqlite3_value*);
double (*value_double)(sqlite3_value*);
int (*value_int)(sqlite3_value*);
sqlite_int64 (*value_int64)(sqlite3_value*);
int (*value_numeric_type)(sqlite3_value*);
const unsigned char * (*value_text)(sqlite3_value*);
const void * (*value_text16)(sqlite3_value*);
const void * (*value_text16be)(sqlite3_value*);
const void * (*value_text16le)(sqlite3_value*);
int (*value_type)(sqlite3_value*);
char *(*vmprintf)(const char*,va_list);
/* Added ??? */
int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
/* Added by 3.3.13 */
int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
int (*clear_bindings)(sqlite3_stmt*);
/* Added by 3.4.1 */
int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
void (*xDestroy)(void *));
/* Added by 3.5.0 */
int (*bind_zeroblob)(sqlite3_stmt*,int,int);
int (*blob_bytes)(sqlite3_blob*);
int (*blob_close)(sqlite3_blob*);
int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
int,sqlite3_blob**);
int (*blob_read)(sqlite3_blob*,void*,int,int);
int (*blob_write)(sqlite3_blob*,const void*,int,int);
int (*create_collation_v2)(sqlite3*,const char*,int,void*,
int(*)(void*,int,const void*,int,const void*),
void(*)(void*));
int (*file_control)(sqlite3*,const char*,int,void*);
sqlite3_int64 (*memory_highwater)(int);
sqlite3_int64 (*memory_used)(void);
sqlite3_mutex *(*mutex_alloc)(int);
void (*mutex_enter)(sqlite3_mutex*);
void (*mutex_free)(sqlite3_mutex*);
void (*mutex_leave)(sqlite3_mutex*);
int (*mutex_try)(sqlite3_mutex*);
int (*open_v2)(const char*,sqlite3**,int,const char*);
int (*release_memory)(int);
void (*result_error_nomem)(sqlite3_context*);
void (*result_error_toobig)(sqlite3_context*);
int (*sleep)(int);
void (*soft_heap_limit)(int);
sqlite3_vfs *(*vfs_find)(const char*);
int (*vfs_register)(sqlite3_vfs*,int);
int (*vfs_unregister)(sqlite3_vfs*);
int (*xthreadsafe)(void);
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
int (*extended_errcode)(sqlite3*);
void (*log)(int,const char*,...);
sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
const char *(*sourceid)(void);
int (*stmt_status)(sqlite3_stmt*,int,int);
int (*strnicmp)(const char*,const char*,int);
int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
int (*wal_autocheckpoint)(sqlite3*,int);
int (*wal_checkpoint)(sqlite3*,const char*);
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
int (*vtab_config)(sqlite3*,int op,...);
int (*vtab_on_conflict)(sqlite3*);
/* Version 3.7.16 and later */
int (*close_v2)(sqlite3*);
const char *(*db_filename)(sqlite3*,const char*);
int (*db_readonly)(sqlite3*,const char*);
int (*db_release_memory)(sqlite3*);
const char *(*errstr)(int);
int (*stmt_busy)(sqlite3_stmt*);
int (*stmt_readonly)(sqlite3_stmt*);
int (*stricmp)(const char*,const char*);
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
void(*)(void*));
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
void(*)(void*),unsigned char);
int (*cancel_auto_extension)(void(*)(void));
int (*load_extension)(sqlite3*,const char*,const char*,char**);
void *(*malloc64)(sqlite3_uint64);
sqlite3_uint64 (*msize)(void*);
void *(*realloc64)(void*,sqlite3_uint64);
void (*reset_auto_extension)(void);
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
void(*)(void*));
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
void(*)(void*), unsigned char);
int (*strglob)(const char*,const char*);
/* Version 3.8.11 and later */
sqlite3_value *(*value_dup)(const sqlite3_value*);
void (*value_free)(sqlite3_value*);
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
/* Version 3.9.0 and later */
unsigned int (*value_subtype)(sqlite3_value*);
void (*result_subtype)(sqlite3_context*,unsigned int);
/* Version 3.10.0 and later */
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
int (*strlike)(const char*,const char*,unsigned int);
int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */
int (*system_errno)(sqlite3*);
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
/* Version 3.18.0 and later */
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
/* Version 3.20.0 and later */
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
sqlite3_stmt**,const char**);
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
sqlite3_stmt**,const void**);
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
int (*vtab_nochange)(sqlite3_context*);
int (*value_nochange)(sqlite3_value*);
const char *(*vtab_collation)(sqlite3_index_info*,int);
/* Version 3.24.0 and later */
int (*keyword_count)(void);
int (*keyword_name)(int,const char**,int*);
int (*keyword_check)(const char*,int);
sqlite3_str *(*str_new)(sqlite3*);
char *(*str_finish)(sqlite3_str*);
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
void (*str_append)(sqlite3_str*, const char *zIn, int N);
void (*str_appendall)(sqlite3_str*, const char *zIn);
void (*str_appendchar)(sqlite3_str*, int N, char C);
void (*str_reset)(sqlite3_str*);
int (*str_errcode)(sqlite3_str*);
int (*str_length)(sqlite3_str*);
char *(*str_value)(sqlite3_str*);
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void (*xValue)(sqlite3_context*),
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
void(*xDestroy)(void*));
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
sqlite3 *db, /* Handle to the database. */
char **pzErrMsg, /* Used to set error string on failure. */
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
);
/*
** The following macros redefine the API routines so that they are
** redirected through the global sqlite3_api structure.
**
** This header file is also used by the loadext.c source file
** (part of the main SQLite library - not an extension) so that
** it can get access to the sqlite3_api_routines structure
** definition. But the main library does not want to redefine
** the API. So the redefinition macros are only valid if the
** SQLITE_CORE macros is undefined.
*/
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
#endif
#define sqlite3_bind_blob sqlite3_api->bind_blob
#define sqlite3_bind_double sqlite3_api->bind_double
#define sqlite3_bind_int sqlite3_api->bind_int
#define sqlite3_bind_int64 sqlite3_api->bind_int64
#define sqlite3_bind_null sqlite3_api->bind_null
#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count
#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index
#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name
#define sqlite3_bind_text sqlite3_api->bind_text
#define sqlite3_bind_text16 sqlite3_api->bind_text16
#define sqlite3_bind_value sqlite3_api->bind_value
#define sqlite3_busy_handler sqlite3_api->busy_handler
#define sqlite3_busy_timeout sqlite3_api->busy_timeout
#define sqlite3_changes sqlite3_api->changes
#define sqlite3_close sqlite3_api->close
#define sqlite3_collation_needed sqlite3_api->collation_needed
#define sqlite3_collation_needed16 sqlite3_api->collation_needed16
#define sqlite3_column_blob sqlite3_api->column_blob
#define sqlite3_column_bytes sqlite3_api->column_bytes
#define sqlite3_column_bytes16 sqlite3_api->column_bytes16
#define sqlite3_column_count sqlite3_api->column_count
#define sqlite3_column_database_name sqlite3_api->column_database_name
#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
#define sqlite3_column_decltype sqlite3_api->column_decltype
#define sqlite3_column_decltype16 sqlite3_api->column_decltype16
#define sqlite3_column_double sqlite3_api->column_double
#define sqlite3_column_int sqlite3_api->column_int
#define sqlite3_column_int64 sqlite3_api->column_int64
#define sqlite3_column_name sqlite3_api->column_name
#define sqlite3_column_name16 sqlite3_api->column_name16
#define sqlite3_column_origin_name sqlite3_api->column_origin_name
#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16
#define sqlite3_column_table_name sqlite3_api->column_table_name
#define sqlite3_column_table_name16 sqlite3_api->column_table_name16
#define sqlite3_column_text sqlite3_api->column_text
#define sqlite3_column_text16 sqlite3_api->column_text16
#define sqlite3_column_type sqlite3_api->column_type
#define sqlite3_column_value sqlite3_api->column_value
#define sqlite3_commit_hook sqlite3_api->commit_hook
#define sqlite3_complete sqlite3_api->complete
#define sqlite3_complete16 sqlite3_api->complete16
#define sqlite3_create_collation sqlite3_api->create_collation
#define sqlite3_create_collation16 sqlite3_api->create_collation16
#define sqlite3_create_function sqlite3_api->create_function
#define sqlite3_create_function16 sqlite3_api->create_function16
#define sqlite3_create_module sqlite3_api->create_module
#define sqlite3_create_module_v2 sqlite3_api->create_module_v2
#define sqlite3_data_count sqlite3_api->data_count
#define sqlite3_db_handle sqlite3_api->db_handle
#define sqlite3_declare_vtab sqlite3_api->declare_vtab
#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache
#define sqlite3_errcode sqlite3_api->errcode
#define sqlite3_errmsg sqlite3_api->errmsg
#define sqlite3_errmsg16 sqlite3_api->errmsg16
#define sqlite3_exec sqlite3_api->exec
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_expired sqlite3_api->expired
#endif
#define sqlite3_finalize sqlite3_api->finalize
#define sqlite3_free sqlite3_api->free
#define sqlite3_free_table sqlite3_api->free_table
#define sqlite3_get_autocommit sqlite3_api->get_autocommit
#define sqlite3_get_auxdata sqlite3_api->get_auxdata
#define sqlite3_get_table sqlite3_api->get_table
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_global_recover sqlite3_api->global_recover
#endif
#define sqlite3_interrupt sqlite3_api->interruptx
#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid
#define sqlite3_libversion sqlite3_api->libversion
#define sqlite3_libversion_number sqlite3_api->libversion_number
#define sqlite3_malloc sqlite3_api->malloc
#define sqlite3_mprintf sqlite3_api->mprintf
#define sqlite3_open sqlite3_api->open
#define sqlite3_open16 sqlite3_api->open16
#define sqlite3_prepare sqlite3_api->prepare
#define sqlite3_prepare16 sqlite3_api->prepare16
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_profile sqlite3_api->profile
#define sqlite3_progress_handler sqlite3_api->progress_handler
#define sqlite3_realloc sqlite3_api->realloc
#define sqlite3_reset sqlite3_api->reset
#define sqlite3_result_blob sqlite3_api->result_blob
#define sqlite3_result_double sqlite3_api->result_double
#define sqlite3_result_error sqlite3_api->result_error
#define sqlite3_result_error16 sqlite3_api->result_error16
#define sqlite3_result_int sqlite3_api->result_int
#define sqlite3_result_int64 sqlite3_api->result_int64
#define sqlite3_result_null sqlite3_api->result_null
#define sqlite3_result_text sqlite3_api->result_text
#define sqlite3_result_text16 sqlite3_api->result_text16
#define sqlite3_result_text16be sqlite3_api->result_text16be
#define sqlite3_result_text16le sqlite3_api->result_text16le
#define sqlite3_result_value sqlite3_api->result_value
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
#define sqlite3_total_changes sqlite3_api->total_changes
#define sqlite3_trace sqlite3_api->trace
#ifndef SQLITE_OMIT_DEPRECATED
#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings
#endif
#define sqlite3_update_hook sqlite3_api->update_hook
#define sqlite3_user_data sqlite3_api->user_data
#define sqlite3_value_blob sqlite3_api->value_blob
#define sqlite3_value_bytes sqlite3_api->value_bytes
#define sqlite3_value_bytes16 sqlite3_api->value_bytes16
#define sqlite3_value_double sqlite3_api->value_double
#define sqlite3_value_int sqlite3_api->value_int
#define sqlite3_value_int64 sqlite3_api->value_int64
#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type
#define sqlite3_value_text sqlite3_api->value_text
#define sqlite3_value_text16 sqlite3_api->value_text16
#define sqlite3_value_text16be sqlite3_api->value_text16be
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
#define sqlite3_clear_bindings sqlite3_api->clear_bindings
#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob
#define sqlite3_blob_bytes sqlite3_api->blob_bytes
#define sqlite3_blob_close sqlite3_api->blob_close
#define sqlite3_blob_open sqlite3_api->blob_open
#define sqlite3_blob_read sqlite3_api->blob_read
#define sqlite3_blob_write sqlite3_api->blob_write
#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2
#define sqlite3_file_control sqlite3_api->file_control
#define sqlite3_memory_highwater sqlite3_api->memory_highwater
#define sqlite3_memory_used sqlite3_api->memory_used
#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc
#define sqlite3_mutex_enter sqlite3_api->mutex_enter
#define sqlite3_mutex_free sqlite3_api->mutex_free
#define sqlite3_mutex_leave sqlite3_api->mutex_leave
#define sqlite3_mutex_try sqlite3_api->mutex_try
#define sqlite3_open_v2 sqlite3_api->open_v2
#define sqlite3_release_memory sqlite3_api->release_memory
#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem
#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig
#define sqlite3_sleep sqlite3_api->sleep
#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit
#define sqlite3_vfs_find sqlite3_api->vfs_find
#define sqlite3_vfs_register sqlite3_api->vfs_register
#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister
#define sqlite3_threadsafe sqlite3_api->xthreadsafe
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
#define sqlite3_stmt_status sqlite3_api->stmt_status
#define sqlite3_strnicmp sqlite3_api->strnicmp
#define sqlite3_unlock_notify sqlite3_api->unlock_notify
#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
#define sqlite3_wal_hook sqlite3_api->wal_hook
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
#define sqlite3_vtab_config sqlite3_api->vtab_config
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
/* Version 3.7.16 and later */
#define sqlite3_close_v2 sqlite3_api->close_v2
#define sqlite3_db_filename sqlite3_api->db_filename
#define sqlite3_db_readonly sqlite3_api->db_readonly
#define sqlite3_db_release_memory sqlite3_api->db_release_memory
#define sqlite3_errstr sqlite3_api->errstr
#define sqlite3_stmt_busy sqlite3_api->stmt_busy
#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
#define sqlite3_stricmp sqlite3_api->stricmp
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
#define sqlite3_bind_text64 sqlite3_api->bind_text64
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
#define sqlite3_load_extension sqlite3_api->load_extension
#define sqlite3_malloc64 sqlite3_api->malloc64
#define sqlite3_msize sqlite3_api->msize
#define sqlite3_realloc64 sqlite3_api->realloc64
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
#define sqlite3_result_blob64 sqlite3_api->result_blob64
#define sqlite3_result_text64 sqlite3_api->result_text64
#define sqlite3_strglob sqlite3_api->strglob
/* Version 3.8.11 and later */
#define sqlite3_value_dup sqlite3_api->value_dup
#define sqlite3_value_free sqlite3_api->value_free
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
/* Version 3.9.0 and later */
#define sqlite3_value_subtype sqlite3_api->value_subtype
#define sqlite3_result_subtype sqlite3_api->result_subtype
/* Version 3.10.0 and later */
#define sqlite3_status64 sqlite3_api->status64
#define sqlite3_strlike sqlite3_api->strlike
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
/* Version 3.18.0 and later */
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
/* Version 3.20.0 and later */
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
/* Version 3.22.0 and later */
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
#define sqlite3_value_nochange sqlite3_api->value_nochange
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
/* Version 3.24.0 and later */
#define sqlite3_keyword_count sqlite3_api->keyword_count
#define sqlite3_keyword_name sqlite3_api->keyword_name
#define sqlite3_keyword_check sqlite3_api->keyword_check
#define sqlite3_str_new sqlite3_api->str_new
#define sqlite3_str_finish sqlite3_api->str_finish
#define sqlite3_str_appendf sqlite3_api->str_appendf
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
#define sqlite3_str_append sqlite3_api->str_append
#define sqlite3_str_appendall sqlite3_api->str_appendall
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
#define sqlite3_str_reset sqlite3_api->str_reset
#define sqlite3_str_errcode sqlite3_api->str_errcode
#define sqlite3_str_length sqlite3_api->str_length
#define sqlite3_str_value sqlite3_api->str_value
/* Version 3.25.0 and later */
#define sqlite3_create_window_function sqlite3_api->create_window_function
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
/* This case when the file really is being compiled as a loadable
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
# define SQLITE_EXTENSION_INIT3 \
extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* SQLITE3EXT_H */

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "bench.h"
uint64_t now_micros() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (uint64_t)(tv.tv_sec * 1000000 + tv.tv_usec);
}
/*
* https://stackoverflow.com/questions/4770985/how-to-check-if-a-string-starts-with-another-string-in-c
*/
bool starts_with(const char* str, const char* pre) {
size_t lenpre = strlen(pre);
size_t lenstr = strlen(str);
return lenstr < lenpre ? false : !strncmp(pre, str, lenpre);
}
char* trim_space(const char* s) {
size_t start = 0;
while (start < strlen(s) && isspace(s[start])) {
start++;
}
size_t limit = strlen(s);
while (limit > start && isspace(s[limit - 1])) {
limit--;
}
char* res = calloc(sizeof(char), limit - start + 1);
for (size_t i = 0; i < limit - start; i++)
res[i] = s[start + i];
res[limit - start] = '\0';
return res;
}