forestdb.ffi: Make fdb_iterator_opt_t its own type and remove comment.

forestdb.lib: Implement iterators and some related stuff.
Document possible bugs for now.
forestdb.lib-tests: Test iterators.
db4
Doug Coleman 2014-11-06 18:24:25 -08:00
parent 046e815a8c
commit 76b14d1bea
3 changed files with 215 additions and 13 deletions

View File

@ -16,7 +16,6 @@ CONSTANT: FDB_MAX_METALEN 65535
CONSTANT: FDB_MAX_BODYLEN 4294967295 CONSTANT: FDB_MAX_BODYLEN 4294967295
! TYPEDEF: uint32_t fdb_open_flags ! TYPEDEF: uint32_t fdb_open_flags
TYPEDEF: uint64_t fdb_seqnum_t TYPEDEF: uint64_t fdb_seqnum_t
TYPEDEF: uint8_t fdb_iterator_opt_t
CONSTANT: FDB_SNAPSHOT_INMEM -1 CONSTANT: FDB_SNAPSHOT_INMEM -1
! typedef int (*fdb_custom_cmp_fixed)(void *a, void *b); ! typedef int (*fdb_custom_cmp_fixed)(void *a, void *b);
@ -49,6 +48,11 @@ ENUM: fdb_compaction_mode_t
{ FDB_COMPACTION_MANUAL 0 } { FDB_COMPACTION_MANUAL 0 }
{ FDB_COMPACTION_AUTO 1 } ; { FDB_COMPACTION_AUTO 1 } ;
ENUM: fdb_iterator_opt_t
{ FDB_ITR_NONE 0 }
{ FDB_ITR_METAONLY 1 }
{ FDB_ITR_NO_DELETES 2 } ;
ENUM: fdb_isolation_level_t ENUM: fdb_isolation_level_t
{ FDB_ISOLATION_SERIALIZABLE 0 } { FDB_ISOLATION_SERIALIZABLE 0 }
{ FDB_ISOLATION_REPEATABLE_READ 1 } { FDB_ISOLATION_REPEATABLE_READ 1 }

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types alien.data alien.strings arrays USING: accessors alien.c-types alien.data alien.strings arrays
assocs combinators continuations destructors forestdb.ffi fry assocs combinators continuations destructors forestdb.ffi fry
io.directories io.files.temp io.pathnames kernel libc io.directories io.files.temp io.pathnames kernel libc make
math.parser math.ranges multiline namespaces sequences math.parser math.ranges multiline namespaces sequences
tools.test ; tools.test ;
IN: forestdb.lib IN: forestdb.lib
@ -208,3 +208,78 @@ IN: forestdb.lib
] with-forestdb-snapshot ] with-forestdb-snapshot
] with-forestdb-path ] with-forestdb-path
] unit-test ] unit-test
! Iterators test
! No matching keys
{
{ }
} [
delete-test-db-1
test-db-1 [
5 set-kv-n
fdb-commit-normal
[
"omg" "nada" [
fdb_doc>doc [ seqnum>> ] [ key>> ] [ body>> ] tri 3array ,
] with-fdb-normal-iterator
] { } make
] with-forestdb-path
] unit-test
! All the keys
{
{
{ 1 "key1" "val1" }
{ 2 "key2" "val2" }
{ 3 "key3" "val3" }
{ 4 "key4" "val4" }
{ 5 "key5" "val5" }
}
} [
delete-test-db-1
test-db-1 [
5 set-kv-n
fdb-commit-normal
[
"key1" "key5" [
fdb_doc>doc [ seqnum>> ] [ key>> ] [ body>> ] tri 3array ,
] with-fdb-normal-iterator
] { } make
] with-forestdb-path
] unit-test
! Test that keys at extremes get returned
{
{
{ 1 "key1" "val1" }
}
} [
delete-test-db-1
test-db-1 [
5 set-kv-n
fdb-commit-normal
[
"key0" "key1" [
fdb_doc>doc [ seqnum>> ] [ key>> ] [ body>> ] tri 3array ,
] with-fdb-normal-iterator
] { } make
] with-forestdb-path
] unit-test
{
{
{ 5 "key5" "val5" }
}
} [
delete-test-db-1
test-db-1 [
5 set-kv-n
fdb-commit-normal
[
"key5" "key9" [
fdb_doc>doc [ seqnum>> ] [ key>> ] [ body>> ] tri 3array ,
] with-fdb-normal-iterator
] { } make
] with-forestdb-path
] unit-test

View File

@ -1,12 +1,43 @@
! Copyright (C) 2014 Doug Coleman. ! Copyright (C) 2014 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types alien.data alien.strings USING: accessors alien.c-types alien.data alien.strings
alien.syntax classes.struct combinators continuations alien.syntax classes.struct combinators constructors
destructors forestdb.ffi fry generalizations io.encodings.string continuations destructors forestdb.ffi fry generalizations
io.encodings.utf8 io.pathnames kernel libc multiline namespaces io.encodings.string io.encodings.utf8 io.pathnames kernel libc
sequences ; math multiline namespaces sequences ;
IN: forestdb.lib IN: forestdb.lib
/*
! Possible bugs in foresdtb:
! why is meta set but metalen is 0?
! also, there is no meta info in these docs
delete-test-db-1
test-db-1 [
5 set-kv-n
fdb-commit-normal
"key1" "key5" [
.
] with-fdb-normal-meta-iterator
] with-forestdb-path
...
S{ fdb_doc
{ keylen 4 }
{ metalen 0 }
{ bodylen 4 }
{ size_ondisk 0 }
{ key ALIEN: 12721e3f0 }
{ seqnum 5 }
{ offset 4256 }
{ meta ALIEN: 1272308d0 }
{ body f }
{ deleted f }
}
! snapshot has doc_count of entire file, not in that snapshot
*/
ERROR: fdb-error error ; ERROR: fdb-error error ;
: fdb-check-error ( ret -- ) : fdb-check-error ( ret -- )
@ -26,6 +57,7 @@ M: fdb-handle dispose*
TUPLE: fdb-doc < disposable doc ; TUPLE: fdb-doc < disposable doc ;
M: fdb-doc dispose* M: fdb-doc dispose*
fdb_doc_free fdb-check-error ; fdb_doc_free fdb-check-error ;
@ -115,16 +147,107 @@ FUNCTION: fdb_status fdb_rollback ( fdb_handle** handle_ptr, fdb_seqnum_t rollba
[ fdb_rollback fdb-check-error ] 2keep drop [ fdb_rollback fdb-check-error ] 2keep drop
void* deref <fdb-handle> fdb-current set ; void* deref <fdb-handle> fdb-current set ;
TUPLE: fdb-iterator < disposable handle ;
: <fdb-iterator> ( handle -- obj )
fdb-iterator new-disposable
swap >>handle ; inline
M: fdb-iterator dispose*
handle>> fdb_iterator_close fdb-check-error ;
: fdb-iterator-init ( start-key end-key fdb_iterator_opt_t -- iterator )
[ get-handle f void* <ref> ] 3dip
[ [ dup length ] bi@ ] dip
[ fdb_iterator_init fdb-check-error ] 7 nkeep 5 ndrop nip
void* deref <fdb-iterator> ;
: fdb-iterator-init-none ( start-key end-key -- iterator )
FDB_ITR_NONE fdb-iterator-init ;
: fdb-iterator-meta-only ( start-key end-key -- iterator )
FDB_ITR_METAONLY fdb-iterator-init ;
: fdb-iterator-no-deletes ( start-key end-key -- iterator )
FDB_ITR_NO_DELETES fdb-iterator-init ;
: check-iterate-result ( doc fdb_status -- doc/f )
{
{ FDB_RESULT_SUCCESS [ void* deref fdb_doc memory>struct ] }
{ FDB_RESULT_ITERATOR_FAIL [ drop f ] }
[ throw ]
} case ;
: fdb-iterate ( iterator word -- doc )
'[
fdb_doc <struct> fdb_doc <ref>
[ _ execute ] keep swap check-iterate-result
] call ; inline
! fdb_doc key, meta, body only valid inside with-forestdb
! so make a helper word to preserve them outside
TUPLE: doc seqnum key meta body deleted? offset size-ondisk ;
CONSTRUCTOR: <doc> doc ( seqnum key meta body deleted? offset size-ondisk -- obj ) ;
/* /*
FUNCTION: fdb_status fdb_iterator_init ( fdb_handle* handle, fdb_iterator** iterator, c-string start_key, size_t start_keylen, c-string end_key, size_t end_keylen, fdb_iterator_opt_t opt ) ; ! Example fdb_doc and converted doc
FUNCTION: fdb_status fdb_iterator_sequence_init ( fdb_handle* handle, fdb_iterator** iterator, fdb_seqnum_t start_seq, fdb_seqnum_t end_seq, fdb_iterator_opt_t opt ) ; S{ fdb_doc
FUNCTION: fdb_status fdb_iterator_prev ( fdb_iterator* iterator, fdb_doc** doc ) ; { keylen 4 }
FUNCTION: fdb_status fdb_iterator_next ( fdb_iterator* iterator, fdb_doc** doc ) ; { metalen 0 }
FUNCTION: fdb_status fdb_iterator_next_metaonly ( fdb_iterator* iterator, fdb_doc** doc ) ; { bodylen 4 }
FUNCTION: fdb_status fdb_iterator_seek ( fdb_iterator* iterator, c-string seek_key, size_t seek_keylen ) ; { size_ondisk 0 }
FUNCTION: fdb_status fdb_iterator_close ( fdb_iterator* iterator ) ; { key ALIEN: 111e003b0 }
{ seqnum 5 }
{ offset 4256 }
{ meta f }
{ body ALIEN: 111d11740 }
{ deleted f }
}
T{ doc
{ seqnum 5 }
{ key "key5" }
{ body "val5" }
{ offset 4256 }
{ size-ondisk 0 }
}
*/ */
: alien/length>string ( alien n -- string/f )
[ drop f ] [ memory>byte-array utf8 decode ] if-zero ;
: fdb_doc>doc ( fdb_doc -- doc )
{
[ seqnum>> ]
[ [ key>> ] [ keylen>> ] bi alien/length>string ]
[ [ meta>> ] [ metalen>> ] bi alien/length>string ]
[ [ body>> ] [ bodylen>> ] bi alien/length>string ]
[ deleted>> >boolean ]
[ offset>> ]
[ size_ondisk>> ]
} cleave <doc> ;
: fdb-iterator-prev ( iterator -- doc/f ) \ fdb_iterator_prev fdb-iterate ;
: fdb-iterator-next ( iterator -- doc/f ) \ fdb_iterator_next fdb-iterate ;
: fdb-iterator-next-meta-only ( iterator -- doc/f ) \ fdb_iterator_next_metaonly fdb-iterate ;
: fdb-iterator-seek ( iterator key -- )
dup length fdb_iterator_seek fdb-check-error ;
: with-fdb-iterator ( start-key end-key fdb_iterator_opt_t iterator-next quot: ( obj -- ) -- )
[ fdb-iterator-init ] 2dip pick '[
[ _ handle>> _ execute [ [ @ ] when* ] keep ] loop
_ &dispose drop
] with-destructors ; inline
: with-fdb-normal-iterator ( start-key end-key quot -- )
[ FDB_ITR_NONE \ fdb-iterator-next ] dip with-fdb-iterator ; inline
! XXX: broken?
: with-fdb-normal-meta-iterator ( start-key end-key quot -- )
[ FDB_ITR_NONE \ fdb-iterator-next-meta-only ] dip with-fdb-iterator ; inline
! Do not try to commit here, as it will fail with FDB_RESULT_RONLY_VIOLATION ! Do not try to commit here, as it will fail with FDB_RESULT_RONLY_VIOLATION
! fdb-current is weird, it gets replaced if you call fdb-rollback ! fdb-current is weird, it gets replaced if you call fdb-rollback
! Therefore, only clean up fdb-current once, and clean it up at the end ! Therefore, only clean up fdb-current once, and clean it up at the end