lets/priv/test/qc_statemc_lets.c
2011-11-02 01:12:39 +09:00

465 lines
13 KiB
C

// %%% The MIT License
// %%%
// %%% Copyright (C) 2011 by Joseph Wayne Norton <norton@alum.mit.edu>
// %%%
// %%% Permission is hereby granted, free of charge, to any person obtaining a copy
// %%% of this software and associated documentation files (the "Software"), to deal
// %%% in the Software without restriction, including without limitation the rights
// %%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// %%% copies of the Software, and to permit persons to whom the Software is
// %%% furnished to do so, subject to the following conditions:
// %%%
// %%% The above copyright notice and this permission notice shall be included in
// %%% all copies or substantial portions of the Software.
// %%%
// %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// %%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// %%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// %%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// %%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// %%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// %%% THE SOFTWARE.
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "qc_statemc_lets.h"
// %%%===================================================================
// %%% API
// %%%===================================================================
//
// setup() ->
// Options = [{c_src,"../c_src/leveldb/include/leveldb/c.h"},
// {additional_files, ["../c_src/leveldb/lib/libleveldb.a", "../c_src/snappy/lib/libsnappy.a"]},
// {cflags, "-lstdc++ -lpthread"}],
// eqc_c:start(leveldb, Options).
//
// teardown() ->
// os:cmd("rm -rf " ++ ?MODULE_STRING).
//
// is_db({ptr, {struct, leveldb_t}, _}) ->
// true;
// is_db(_) ->
// false.
// open() ->
// Options = leveldb:leveldb_options_create(),
// try
// Leveldb:leveldb_options_set_create_if_missing(Options, 1),
// leveldb:leveldb_options_set_error_if_exists(Options, 1),
// open(Options)
// after
// leveldb:leveldb_options_destroy(Options)
// end.
leveldb_t* open0() {
leveldb_options_t* Options = leveldb_options_create();
leveldb_options_set_create_if_missing(Options, 1);
leveldb_options_set_error_if_exists(Options, 1);
leveldb_t* Db = open1(Options);
leveldb_options_destroy(Options);
return Db;
}
// open(Options) ->
// ErrPtr = errptr(),
// try
// case leveldb:leveldb_open(Options, ?MODULE_STRING, ErrPtr) of
// {ptr, {struct, leveldb_t}, 0} ->
// read_errptr(ErrPtr);
// {ptr, {struct, leveldb_t}, _}=Db ->
// Db
// end
// after
// free_ptr(ErrPtr)
// end.
leveldb_t* open1(leveldb_options_t* Options) {
char* ErrPtr = NULL;
leveldb_t* Db = leveldb_open(Options, "qc_leveldb", &ErrPtr);
assert(ErrPtr == NULL);
return Db;
}
// reopen() ->
// Options = leveldb:leveldb_options_create(),
// try
// reopen(Options)
// after
// leveldb:leveldb_options_destroy(Options)
// end.
leveldb_t* reopen0() {
leveldb_options_t* Options = leveldb_options_create();
leveldb_t* Db = reopen1(Options);
leveldb_options_destroy(Options);
return Db;
}
// reopen(Options) ->
// ErrPtr = errptr(),
// try
// case leveldb:leveldb_open(Options, ?MODULE_STRING, ErrPtr) of
// {ptr, {struct, leveldb_t}, 0} ->
// read_errptr(ErrPtr);
// {ptr, {struct, leveldb_t}, _}=Db ->
// Db
// end
// after
// free_ptr(ErrPtr)
// end.
leveldb_t* reopen1(leveldb_options_t* Options) {
char* ErrPtr = NULL;
leveldb_t* Db = leveldb_open(Options, "qc_leveldb", &ErrPtr);
assert(ErrPtr == NULL);
return Db;
}
// close(Db) ->
// ok == leveldb:leveldb_close(Db).
void close1(leveldb_t* Db) {
leveldb_close(Db);
return;
}
// put(Db, Obj) ->
// Options = leveldb:leveldb_writeoptions_create(),
// try
// put(Db, Options, Obj)
// after
// leveldb:leveldb_writeoptions_destroy(Options)
// end.
void put2(leveldb_t* Db, char* Key, size_t KeyLen, char* Val, size_t ValLen) {
leveldb_writeoptions_t* Options = leveldb_writeoptions_create();
put3(Db, Key, KeyLen, Val, ValLen, Options);
leveldb_writeoptions_destroy(Options);
return;
}
// put(Db, Options, {obj,Key,Val}) ->
// ErrPtr = errptr(),
// try
// leveldb:leveldb_put(Db, Options, binary_to_list(Key), byte_size(Key), binary_to_list(Val), byte_size(Val), ErrPtr),
// read_errptr(ErrPtr)
// after
// free_ptr(ErrPtr)
// end.
void put3(leveldb_t* Db, char* Key, size_t KeyLen, char* Val, size_t ValLen, const leveldb_writeoptions_t* Options) {
char* ErrPtr = NULL;
leveldb_put(Db, Options, Key, KeyLen, Val, ValLen, &ErrPtr);
assert(ErrPtr == NULL);
return;
}
// delete(Db, Key) ->
// Options = leveldb:leveldb_writeoptions_create(),
// try
// delete(Db, Options, Key)
// after
// leveldb:leveldb_writeoptions_destroy(Options)
// end.
void delete2(leveldb_t* Db, char* Key, size_t KeyLen) {
leveldb_writeoptions_t* Options = leveldb_writeoptions_create();
delete3(Db, Key, KeyLen, Options);
leveldb_writeoptions_destroy(Options);
return;
}
// delete(Db, Options, Key) ->
// ErrPtr = errptr(),
// try
// leveldb:leveldb_delete(Db, Options, binary_to_list(Key), byte_size(Key), ErrPtr),
// read_errptr(ErrPtr)
// after
// free_ptr(ErrPtr)
// end.
void delete3(leveldb_t* Db, char* Key, size_t KeyLen, const leveldb_writeoptions_t* Options) {
char* ErrPtr = NULL;
leveldb_delete(Db, Options, Key, KeyLen, &ErrPtr);
assert(ErrPtr == NULL);
return;
}
// get(Db, Key) ->
// Options = leveldb:leveldb_readoptions_create(),
// try
// get(Db, Options, Key)
// after
// leveldb:leveldb_readoptions_destroy(Options)
// end.
char* get2(leveldb_t* Db, char* Key, size_t KeyLen, size_t* ValLen) {
leveldb_readoptions_t* Options = leveldb_readoptions_create();
char* Val = get3(Db, Key, KeyLen, ValLen, Options);
leveldb_readoptions_destroy(Options);
return Val;
}
// get(Db, Options, Key) ->
// ErrPtr = errptr(),
// LenPtr = lenptr(),
// try
// case leveldb:leveldb_get(Db, Options, binary_to_list(Key), byte_size(Key), LenPtr, ErrPtr) of
// 0 ->
// read_errptr(ErrPtr);
// ValPtr ->
// read_binary(ValPtr, LenPtr)
// end
// after
// free_ptr(ErrPtr),
// free_ptr(LenPtr)
// end.
char* get3(leveldb_t* Db, char* Key, size_t KeyLen, size_t* ValLen, const leveldb_readoptions_t* Options) {
char* ErrPtr = NULL;
char* Val = leveldb_get(Db, Options, Key, KeyLen, ValLen, &ErrPtr);
assert(ErrPtr == NULL);
return Val;
}
// first(Db) ->
// Options = leveldb:leveldb_readoptions_create(),
// try
// first(Db, Options)
// after
// leveldb:leveldb_readoptions_destroy(Options)
// end.
char* first1(leveldb_t* Db, size_t *KeyLen) {
leveldb_readoptions_t* Options = leveldb_readoptions_create();
char* Key = first2(Db, KeyLen, Options);
leveldb_readoptions_destroy(Options);
return Key;
}
// first(Db, Options) ->
// Iter = leveldb:leveldb_create_iterator(Db, Options),
// LenPtr = lenptr(),
// try
// leveldb:leveldb_iter_seek_to_first(Iter),
// case leveldb:leveldb_iter_valid(Iter) of
// 0 ->
// true;
// 1 ->
// KeyPtr = leveldb:leveldb_iter_key(Iter, LenPtr),
// read_binary(KeyPtr, LenPtr)
// end
// after
// leveldb:leveldb_iter_destroy(Iter),
// free_ptr(LenPtr)
// end.
char* first2(leveldb_t* Db, size_t* KeyLen, const leveldb_readoptions_t* Options) {
leveldb_iterator_t* Iter = leveldb_create_iterator(Db, Options);
char* Key = NULL;
*KeyLen = 0;
leveldb_iter_seek_to_first(Iter);
if (leveldb_iter_valid(Iter)) {
Key = (char*) leveldb_iter_key(Iter, KeyLen);
Key = read_binary(Key, KeyLen);
}
leveldb_iter_destroy(Iter);
return Key;
}
// last(Db) ->
// Options = leveldb:leveldb_readoptions_create(),
// try
// last(Db, Options)
// after
// leveldb:leveldb_readoptions_destroy(Options)
// end.
char* last1(leveldb_t* Db, size_t *KeyLen) {
leveldb_readoptions_t* Options = leveldb_readoptions_create();
char* Key = last2(Db, KeyLen, Options);
leveldb_readoptions_destroy(Options);
return Key;
}
// last(Db, Options) ->
// Iter = leveldb:leveldb_create_iterator(Db, Options),
// LenPtr = lenptr(),
// try
// leveldb:leveldb_iter_seek_to_last(Iter),
// case leveldb:leveldb_iter_valid(Iter) of
// 0 ->
// true;
// 1 ->
// KeyPtr = leveldb:leveldb_iter_key(Iter, LenPtr),
// read_binary(KeyPtr, LenPtr)
// end
// after
// leveldb:leveldb_iter_destroy(Iter),
// free_ptr(LenPtr)
// end.
char* last2(leveldb_t* Db, size_t* KeyLen, const leveldb_readoptions_t* Options) {
leveldb_iterator_t* Iter = leveldb_create_iterator(Db, Options);
char* Key = NULL;
*KeyLen = 0;
leveldb_iter_seek_to_last(Iter);
if (leveldb_iter_valid(Iter)) {
Key = (char*) leveldb_iter_key(Iter, KeyLen);
Key = read_binary(Key, KeyLen);
}
leveldb_iter_destroy(Iter);
return Key;
}
// next(Db, Key) ->
// Options = leveldb:leveldb_readoptions_create(),
// try
// next(Db, Key, Options)
// after
// leveldb:leveldb_readoptions_destroy(Options)
// end.
char* next2(leveldb_t* Db, char* Key, size_t KeyLen, size_t *NextKeyLen) {
leveldb_readoptions_t* Options = leveldb_readoptions_create();
char* NextKey = next3(Db, Key, KeyLen, NextKeyLen, Options);
leveldb_readoptions_destroy(Options);
return NextKey;
}
// next(Db, Key, Options) ->
// Iter = leveldb:leveldb_create_iterator(Db, Options),
// LenPtr = lenptr(),
// LenPtr1 = lenptr(),
// try
// leveldb:leveldb_iter_seek(Iter, binary_to_list(Key), byte_size(Key)),
// case leveldb:leveldb_iter_valid(Iter) of
// 0 ->
// true;
// 1 ->
// KeyPtr = leveldb:leveldb_iter_key(Iter, LenPtr),
// K = read_binary(KeyPtr, LenPtr),
// if K =/= Key ->
// K;
// true ->
// leveldb:leveldb_iter_next(Iter),
// case leveldb:leveldb_iter_valid(Iter) of
// 0 ->
// true;
// 1 ->
// KeyPtr1 = leveldb:leveldb_iter_key(Iter, LenPtr1),
// read_binary(KeyPtr1, LenPtr1)
// end
// end
// end
// after
// leveldb:leveldb_iter_destroy(Iter),
// free_ptr(LenPtr),
// free_ptr(LenPtr1)
// end.
char* next3(leveldb_t* Db, char* Key, size_t KeyLen, size_t* NextKeyLen, const leveldb_readoptions_t* Options) {
leveldb_iterator_t* Iter = leveldb_create_iterator(Db, Options);
char* NextKey = NULL;
*NextKeyLen = 0;
leveldb_iter_seek(Iter, Key, KeyLen);
if (leveldb_iter_valid(Iter)) {
NextKey = (char*) leveldb_iter_key(Iter, NextKeyLen);
if (0 == compare_binary(Key, KeyLen, NextKey, *NextKeyLen)) {
leveldb_iter_next(Iter);
if (leveldb_iter_valid(Iter)) {
NextKey = (char*) leveldb_iter_key(Iter, NextKeyLen);
NextKey = read_binary(NextKey, NextKeyLen);
} else {
NextKey = NULL;
*NextKeyLen = 0;
}
} else {
NextKey = read_binary(NextKey, NextKeyLen);
}
}
leveldb_iter_destroy(Iter);
return NextKey;
}
// %%%===================================================================
// %%% Internal
// %%%===================================================================
//
// errptr() ->
// eqc_c:alloc({ptr, char}, [0]).
//
// lenptr() ->
// eqc_c:alloc(unsigned_long, 0).
//
// free_ptr(Ptr) ->
// eqc_c:free(Ptr).
//
// read_errptr(ErrPtr) ->
// case eqc_c:read_string(eqc_c:deref(ErrPtr)) of
// [] ->
// true;
// Err ->
// Err
// end.
//
// read_lenptr(LenPtr) ->
// eqc_c:deref(LenPtr).
//
// read_binary({ptr, char, 0}, _LenPtr) ->
// true;
// read_binary(ValPtr, LenPtr) ->
// list_to_binary(eqc_c:read_array(ValPtr, read_lenptr(LenPtr))).
char* read_binary(const char* B, size_t* BLen) {
char* tmp = malloc(*BLen);
if (tmp) {
tmp = memcpy(tmp, B, *BLen);
} else {
*BLen = 0;
}
return tmp;
}
int compare_binary(const char* A, size_t ALen, const char* B, size_t BLen) {
if (ALen > BLen) {
return 1;
} else if (ALen < BLen) {
return -1;
} else {
return memcmp(A, B, ALen);
}
}