diff --git a/extra/forestdb/paths/authors.txt b/extra/forestdb/paths/authors.txt new file mode 100644 index 0000000000..7c1b2f2279 --- /dev/null +++ b/extra/forestdb/paths/authors.txt @@ -0,0 +1 @@ +Doug Coleman diff --git a/extra/forestdb/paths/paths-tests.factor b/extra/forestdb/paths/paths-tests.factor new file mode 100644 index 0000000000..c4339829ee --- /dev/null +++ b/extra/forestdb/paths/paths-tests.factor @@ -0,0 +1,39 @@ +! Copyright (C) 2014 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: forestdb.paths kernel tools.test ; +IN: forestdb.paths.tests + +{ "1.fq.0" } [ "0.fq.0" next-vnode-name ] unit-test +{ "1.fq.0" } [ "0.fq.1" next-vnode-name ] unit-test +{ "100.fq.0" } [ "99.fq.0" next-vnode-name ] unit-test +{ "100.fq.0" } [ "99.fq.1" next-vnode-name ] unit-test +{ "100.fq.0" } [ "99.fq.20" next-vnode-name ] unit-test +{ "100.fq.0" } [ "099.fq.20" next-vnode-name ] unit-test +{ "0100.fq.0" } [ "0099.fq.20" next-vnode-name ] unit-test + +{ "00001.fq.0" } [ "00000.fq.0" next-vnode-name ] unit-test +{ "001.fq.0" } [ "000.fq.1" next-vnode-name ] unit-test +{ "000100.fq.0" } [ "000099.fq.0" next-vnode-name ] unit-test +{ "00100.fq.0" } [ "00099.fq.1" next-vnode-name ] unit-test +{ "00000000100.fq.0" } [ "00000000099.fq.20" next-vnode-name ] unit-test + +{ "0.fq.0" } [ "00.fq.00" canonical-fdb-name ] unit-test +{ "1.fq.0" } [ "01.fq.00" canonical-fdb-name ] unit-test +{ "0.fq.1" } [ "00.fq.01" canonical-fdb-name ] unit-test +{ "100.fq.10" } [ "000100.fq.010" canonical-fdb-name ] unit-test + +{ "0.fq.1" } [ "0.fq.0" next-vnode-version-name ] unit-test +{ "0.fq.2" } [ "0.fq.1" next-vnode-version-name ] unit-test +{ "99.fq.1" } [ "99.fq.0" next-vnode-version-name ] unit-test +{ "99.fq.2" } [ "99.fq.1" next-vnode-version-name ] unit-test +{ "99.fq.21" } [ "99.fq.20" next-vnode-version-name ] unit-test + +[ "fq" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "0.fq" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "0.fq." ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ ".fq.0" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "1fq.0" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "1fq0" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "1.fq0" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "1.fq.0.0" ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with +[ "1.fq.00." ensure-fdb-filename drop ] [ not-an-fdb-filename? ] must-fail-with diff --git a/extra/forestdb/paths/paths.factor b/extra/forestdb/paths/paths.factor new file mode 100644 index 0000000000..af6c397211 --- /dev/null +++ b/extra/forestdb/paths/paths.factor @@ -0,0 +1,84 @@ +! Copyright (C) 2014 Doug Coleman. +! See http://factorcode.org/license.txt for BSD license. +USING: arrays combinators.short-circuit combinators.smart +io.directories io.pathnames kernel math math.parser sequences +sorting sorting.human splitting ; +QUALIFIED: sets +IN: forestdb.paths + +CONSTANT: fdb-filename-base "fq" + +: fdb-filename? ( path -- ? ) + "." split { + [ length 3 = ] + [ second fdb-filename-base = ] + [ first string>number ] + [ third string>number ] + } 1&& ; + +ERROR: not-an-fdb-filename string ; + +: ensure-fdb-filename ( string -- string ) + dup fdb-filename? [ not-an-fdb-filename ] unless ; + +ERROR: not-a-string-number string ; + +: ?string>number ( string -- n ) + dup string>number dup [ nip ] [ not-a-string-number ] if ; + +: change-string-number ( string quot -- string' ) + [ [ string>number ] dip call number>string ] 2keep drop + length CHAR: 0 pad-head ; inline + +: next-vnode-name ( string -- string' ) + [ + "." split + first [ 1 + ] change-string-number + "." fdb-filename-base ".0" + ] "" append-outputs-as ; + +: trim-head-zeros ( string -- string' ) + [ CHAR: 0 = ] trim-head 1 CHAR: 0 pad-head ; + +: canonical-fdb-name ( string -- string' ) + ensure-fdb-filename + "." split first3 + [ trim-head-zeros ] + [ ] + [ trim-head-zeros ] tri* 3array "." join ; + +: next-vnode-version-name ( string -- string' ) + "." split + [ but-last "." join ] + [ last [ 1 + ] change-string-number ] bi "." glue ; + +: path>next-vnode-path ( path -- path' ) + dup directory-files + [ fdb-filename? ] filter + [ human<=> ] sort [ + fdb-filename-base "0." ".0" surround append-path + ] [ + last "." split first [ 1 + ] change-string-number + ".fq.0" append append-path + ] if-empty ; + +: path-has-fdb? ( path -- ? ) + directory-files [ fdb-filename? ] filter length 0 > ; + +: path-only-fdb? ( path -- ? ) + directory-files + [ length ] + [ [ fdb-filename? ] filter length ] bi = ; + +: path-fdb-duplicates ( path -- seq ) + directory-files [ canonical-fdb-name ] map sets:members ; + +: ensure-fdb-directory ( filename -- filename ) + [ make-directories ] keep ; + +: ensure-fdb-filename-directory ( filename -- filename ) + [ parent-directory make-directories ] keep ; + +! : path>next-vnode-version-name ( path -- path' ) + ! [ file-name ] +