@@ -39,6 +39,8 @@ use foundationdb::directory::directory_layer::DirectoryLayer;
3939use foundationdb:: directory:: directory_subspace:: DirectorySubspace ;
4040use foundationdb:: directory:: error:: DirectoryError ;
4141use foundationdb:: directory:: Directory ;
42+ use foundationdb:: tuple:: { PackResult , TupleUnpack } ;
43+
4244use tuple:: VersionstampOffset ;
4345
4446fn mutation_from_str ( s : & str ) -> MutationType {
@@ -644,11 +646,12 @@ impl StackMachine {
644646 let element = self . pop_element ( ) . await ;
645647 match element {
646648 Element :: Bytes ( v) => v,
649+ Element :: Nil => Bytes :: from ( vec ! [ ] ) ,
647650 _ => panic ! ( "bytes were expected, found {:?}" , element) ,
648651 }
649652 }
650653
651- async fn pop_tuple ( & mut self , count : usize ) -> Vec < Vec < String > > {
654+ async fn pop_string_tuple ( & mut self , count : usize ) -> Vec < Vec < String > > {
652655 let mut result = vec ! [ ] ;
653656
654657 if count == 0 {
@@ -1636,7 +1639,7 @@ impl StackMachine {
16361639 // raw_prefix. Append it to the directory list.
16371640 DirectoryCreateSubspace => {
16381641 debug ! ( "CreateSubspace stack: {:?}" , self . stack) ;
1639- let tuple_prefix = self . pop_tuple ( 1 ) . await ;
1642+ let tuple_prefix = self . pop_string_tuple ( 1 ) . await ;
16401643 let raw_prefix = self . pop_bytes ( ) . await ;
16411644 let subspace =
16421645 Subspace :: from_bytes ( & raw_prefix) . subspace ( tuple_prefix. get ( 0 ) . unwrap ( ) ) ;
@@ -1711,7 +1714,7 @@ impl StackMachine {
17111714 DirectoryCreate => {
17121715 debug ! ( "Create stack: {:?}" , self . stack) ;
17131716
1714- let path = self . pop_tuple ( 1 ) . await ;
1717+ let path = self . pop_string_tuple ( 1 ) . await ;
17151718 let bytes_layer = self . pop_bytes ( ) . await ;
17161719 let bytes_prefix = self . pop_bytes ( ) . await ;
17171720
@@ -1728,7 +1731,7 @@ impl StackMachine {
17281731 } ;
17291732
17301733 let directory = self
1731- . get_current_directory ( )
1734+ . get_current_directory_layer ( )
17321735 . expect ( "could not find a directory" ) ;
17331736
17341737 let txn = match trx {
@@ -1765,7 +1768,7 @@ impl StackMachine {
17651768 DirectoryOpen => {
17661769 debug ! ( "DirectoryOpen stack: {:?}" , self . stack) ;
17671770
1768- let path = self . pop_tuple ( 1 ) . await ;
1771+ let path = self . pop_string_tuple ( 1 ) . await ;
17691772 let bytes_layer = self . pop_bytes ( ) . await ;
17701773
17711774 let layer = if bytes_layer. is_empty ( ) {
@@ -1775,7 +1778,7 @@ impl StackMachine {
17751778 } ;
17761779
17771780 let directory = self
1778- . get_current_directory ( )
1781+ . get_current_directory_layer ( )
17791782 . expect ( "could not find a directory" ) ;
17801783
17811784 let txn = match trx {
@@ -1812,7 +1815,7 @@ impl StackMachine {
18121815 DirectoryCreateOrOpen => {
18131816 debug ! ( "CreateOrOpen stack: {:?}" , self . stack) ;
18141817
1815- let path = self . pop_tuple ( 1 ) . await ;
1818+ let path = self . pop_string_tuple ( 1 ) . await ;
18161819 let bytes_layer = self . pop_bytes ( ) . await ;
18171820
18181821 let layer = if bytes_layer. is_empty ( ) {
@@ -1822,7 +1825,7 @@ impl StackMachine {
18221825 } ;
18231826
18241827 let directory = self
1825- . get_current_directory ( )
1828+ . get_current_directory_layer ( )
18261829 . expect ( "could not find a directory" ) ;
18271830
18281831 let txn = match trx {
@@ -1900,10 +1903,10 @@ impl StackMachine {
19001903 DirectoryMove => {
19011904 debug ! ( "Move stack: {:?}" , self . stack) ;
19021905
1903- let paths = self . pop_tuple ( 2 ) . await ;
1906+ let paths = self . pop_string_tuple ( 2 ) . await ;
19041907
19051908 let directory = self
1906- . get_current_directory ( )
1909+ . get_current_directory_layer ( )
19071910 . expect ( "could not find a directory" ) ;
19081911
19091912 let txn = match trx {
@@ -1913,6 +1916,8 @@ impl StackMachine {
19131916 }
19141917 } ;
19151918
1919+ debug ! ( "starting" ) ;
1920+
19161921 match directory
19171922 . move_to (
19181923 txn,
@@ -1934,6 +1939,7 @@ impl StackMachine {
19341939 self . push_directory_err ( & instr. code , number, e) ;
19351940 }
19361941 } ;
1942+ debug ! ( "finished" ) ;
19371943 }
19381944
19391945 // Use the current directory for this operation.
@@ -1943,10 +1949,10 @@ impl StackMachine {
19431949 DirectoryMoveTo => {
19441950 debug ! ( "MoveTo stack: {:?}" , self . stack) ;
19451951
1946- let paths = self . pop_tuple ( 1 ) . await ;
1952+ let paths = self . pop_string_tuple ( 1 ) . await ;
19471953
19481954 let directory = self
1949- . get_current_directory ( )
1955+ . get_current_directory_layer ( )
19501956 . expect ( "could not find a directory" ) ;
19511957
19521958 let txn = match trx {
@@ -1983,10 +1989,10 @@ impl StackMachine {
19831989 DirectoryRemove => {
19841990 debug ! ( "Remove stack: {:?}" , self . stack) ;
19851991 let count = self . pop_usize ( ) . await ;
1986- let paths = self . pop_tuple ( count) . await ;
1992+ let paths = self . pop_string_tuple ( count) . await ;
19871993
19881994 let directory = self
1989- . get_current_directory ( )
1995+ . get_current_directory_layer ( )
19901996 . expect ( "could not find a directory" ) ;
19911997
19921998 let txn = match trx {
@@ -2011,10 +2017,10 @@ impl StackMachine {
20112017 DirectoryRemoveIfExists => {
20122018 debug ! ( "RemoveIfExists stack: {:?}" , self . stack) ;
20132019 let count = self . pop_usize ( ) . await ;
2014- let paths = self . pop_tuple ( count) . await ;
2020+ let paths = self . pop_string_tuple ( count) . await ;
20152021
20162022 let directory = self
2017- . get_current_directory ( )
2023+ . get_current_directory_layer ( )
20182024 . expect ( "could not find a directory" ) ;
20192025
20202026 let txn = match trx {
@@ -2030,7 +2036,10 @@ impl StackMachine {
20302036 . await
20312037 . expect ( "could not check of existence" )
20322038 {
2033- directory. remove ( txn, paths. to_owned ( ) ) . await ;
2039+ directory
2040+ . remove ( txn, paths. to_owned ( ) )
2041+ . await
2042+ . expect ( "could not remove path" ) ;
20342043 }
20352044 }
20362045
@@ -2043,10 +2052,10 @@ impl StackMachine {
20432052 DirectoryList => {
20442053 debug ! ( "List stack: {:?}" , self . stack) ;
20452054 let count = self . pop_usize ( ) . await ;
2046- let paths = self . pop_tuple ( count) . await ;
2055+ let paths = self . pop_string_tuple ( count) . await ;
20472056
20482057 let directory = self
2049- . get_current_directory ( )
2058+ . get_current_directory_layer ( )
20502059 . expect ( "could not find a directory" ) ;
20512060
20522061 let txn = match trx {
@@ -2083,10 +2092,10 @@ impl StackMachine {
20832092 debug ! ( "Exists stack: {:?}" , self . stack) ;
20842093 let count = self . pop_usize ( ) . await ;
20852094
2086- let paths = self . pop_tuple ( count) . await ;
2095+ let paths = self . pop_string_tuple ( count) . await ;
20872096
20882097 let directory = self
2089- . get_current_directory ( )
2098+ . get_current_directory_layer ( )
20902099 . expect ( "could not find a directory" ) ;
20912100
20922101 let txn = match trx {
@@ -2111,19 +2120,58 @@ impl StackMachine {
21112120 //
21122121 // Pop 1 tuple off the stack as [key_tuple]. Pack key_tuple and push the result
21132122 // onto the stack.
2114- DirectoryPackKey => unimplemented ! ( ) ,
2123+ DirectoryPackKey => {
2124+ let n: usize = self . pop_usize ( ) . await ;
2125+ debug ! ( "DirectoryPackKey {}" , n) ;
2126+ let mut buf = Vec :: new ( ) ;
2127+ for _ in 0 ..n {
2128+ let element: Element = self . pop_element ( ) . await ;
2129+ debug ! ( " - {:?}" , element) ;
2130+ buf. push ( element) ;
2131+ }
2132+
2133+ let tuple = Element :: Tuple ( buf) ;
2134+ self . push (
2135+ number,
2136+ Element :: Bytes ( self . pack_with_current_subspace ( & tuple) . unwrap ( ) . into ( ) ) ,
2137+ ) ;
2138+ }
21152139
21162140 // Use the current directory for this operation.
21172141 //
21182142 // Pop 1 item off the stack as [key]. Unpack key and push the resulting tuple
21192143 // onto the stack one item at a time.
2120- DirectoryUnpackKey => unimplemented ! ( ) ,
2144+ DirectoryUnpackKey => {
2145+ let data = self . pop_bytes ( ) . await ;
2146+ debug ! ( "directory_unpack {:?}" , data) ;
2147+ let data: Vec < Element > = self . unpack_with_current_subspace ( & data) . unwrap ( ) . unwrap ( ) ;
2148+ for element in data {
2149+ debug ! ( " - {:?}" , element) ;
2150+ self . push ( number, Element :: Bytes ( pack ( & ( element, ) ) . into ( ) ) ) ;
2151+ }
2152+ }
21212153
21222154 // Use the current directory for this operation.
21232155 //
21242156 // Pop 1 tuple off the stack as [tuple]. Create a range using tuple and push
21252157 // range.begin and range.end onto the stack.
2126- DirectoryRange => unimplemented ! ( ) ,
2158+ DirectoryRange => {
2159+ debug ! ( "directory_range stack: {:?}" , self . stack) ;
2160+ let n: usize = self . pop_usize ( ) . await ;
2161+ debug ! ( "DirectoryRange {}" , n) ;
2162+ let mut buf = Vec :: new ( ) ;
2163+ for _ in 0 ..n {
2164+ let element: Element = self . pop_element ( ) . await ;
2165+ debug ! ( " - {:?}" , element) ;
2166+ buf. push ( element) ;
2167+ }
2168+
2169+ let tuple = Element :: Tuple ( buf) ;
2170+ let subspace = self . subspace_with_current ( & tuple) . unwrap ( ) ;
2171+ let ( begin_range, end_range) = subspace. range ( ) ;
2172+ self . push ( number, Element :: Bytes ( begin_range. into ( ) ) ) ;
2173+ self . push ( number, Element :: Bytes ( end_range. into ( ) ) ) ;
2174+ }
21272175
21282176 // Use the current directory for this operation.
21292177 //
@@ -2142,7 +2190,21 @@ impl StackMachine {
21422190 // Pop 1 item off the stack as [prefix]. Let key equal
21432191 // prefix + tuple.pack([dir_index]). Set key to be the result of calling
21442192 // directory.key() in the current transaction.
2145- DirectoryLogSubspace => unimplemented ! ( ) ,
2193+ DirectoryLogSubspace => {
2194+ debug ! ( "directory_log_subspace stack: {:?}" , self . stack) ;
2195+ let raw_prefix = self . pop_bytes ( ) . await ;
2196+ let txn = match trx {
2197+ TransactionState :: Transaction ( ref t) => t,
2198+ _ => {
2199+ panic ! ( "could not find an active transaction" ) ;
2200+ }
2201+ } ;
2202+
2203+ let directory = self . get_current_directory_subspace ( ) . unwrap ( ) ;
2204+ let key = pack ( & ( self . directory_index , & raw_prefix) ) ;
2205+ let value = directory. bytes ( ) ;
2206+ txn. set ( & key, & value) ;
2207+ }
21462208
21472209 // Use the current directory for this operation.
21482210 //
@@ -2161,7 +2223,45 @@ impl StackMachine {
21612223 //
21622224 // Where log_subspace[u<str>] is the subspace packed tuple containing only the
21632225 // single specified unicode string <str>.
2164- DirectoryLogDirectory => unimplemented ! ( ) ,
2226+ DirectoryLogDirectory => {
2227+ debug ! ( "directory_log_directory stack: {:?}" , self . stack) ;
2228+ let directory = self
2229+ . get_current_directory_layer ( )
2230+ . expect ( "could not find a directory" ) ;
2231+
2232+ let txn = match trx {
2233+ TransactionState :: Transaction ( ref t) => t,
2234+ _ => {
2235+ panic ! ( "could not find an active transaction" ) ;
2236+ }
2237+ } ;
2238+
2239+ let raw_prefix = self . pop_bytes ( ) . await ;
2240+ let subspace = Subspace :: from_bytes ( & * raw_prefix) . subspace ( & ( self . directory_index ) ) ;
2241+
2242+ let key_path = subspace. pack ( & ( String :: from ( "path" ) ) ) ;
2243+ let value_path = pack ( & directory. get_path ( ) ) ;
2244+
2245+ let key_layer = subspace. pack ( & ( String :: from ( "layer" ) ) ) ;
2246+ let value_layer = pack ( & directory. get_layer ( ) ) ;
2247+
2248+ let exists = directory. exists ( & txn, vec ! [ ] ) . await . unwrap ( ) ;
2249+ let key_exists = subspace. pack ( & ( String :: from ( "exists" ) ) ) ;
2250+ let value_exists = pack ( & ( exists as i32 ) ) ;
2251+
2252+ let children = if exists {
2253+ directory. list ( txn, vec ! [ ] ) . await . unwrap ( )
2254+ } else {
2255+ vec ! [ ]
2256+ } ;
2257+ let key_children = subspace. pack ( & ( String :: from ( "children" ) ) ) ;
2258+ let value_children = pack ( & children) ;
2259+
2260+ txn. set ( & key_path, & value_path) ;
2261+ txn. set ( & key_layer, & value_layer) ;
2262+ txn. set ( & key_exists, & value_exists) ;
2263+ txn. set ( & key_children, & value_children) ;
2264+ }
21652265
21662266 // Use the current directory for this operation.
21672267 //
@@ -2210,7 +2310,7 @@ impl StackMachine {
22102310 handle. join ( ) . expect ( "joined thread to not panic" ) ;
22112311 }
22122312 }
2213- fn get_current_directory ( & self ) -> Option < Box < dyn Directory > > {
2313+ fn get_current_directory_layer ( & self ) -> Option < Box < dyn Directory > > {
22142314 debug ! ( "current directory is at index {}" , self . directory_index) ;
22152315 match self . directory_stack . get ( self . directory_index ) {
22162316 None => None ,
@@ -2221,6 +2321,53 @@ impl StackMachine {
22212321 } ,
22222322 }
22232323 }
2324+
2325+ fn pack_with_current_subspace < T : TuplePack > ( & self , v : & T ) -> Option < Vec < u8 > > {
2326+ match self . directory_stack . get ( self . directory_index ) {
2327+ None => None ,
2328+ Some ( directory_or_subspace) => match directory_or_subspace {
2329+ DirectoryStackItem :: DirectorySubspace ( d) => Some ( d. pack ( v) ) ,
2330+ DirectoryStackItem :: Subspace ( d) => Some ( d. pack ( v) ) ,
2331+ _ => None ,
2332+ } ,
2333+ }
2334+ }
2335+
2336+ fn unpack_with_current_subspace < ' de , T : TupleUnpack < ' de > > (
2337+ & self ,
2338+ key : & ' de [ u8 ] ,
2339+ ) -> Option < PackResult < T > > {
2340+ match self . directory_stack . get ( self . directory_index ) {
2341+ None => None ,
2342+ Some ( directory_or_subspace) => match directory_or_subspace {
2343+ DirectoryStackItem :: DirectorySubspace ( d) => Some ( d. unpack ( key) ) ,
2344+ DirectoryStackItem :: Subspace ( d) => Some ( d. unpack ( key) ) ,
2345+ _ => None ,
2346+ } ,
2347+ }
2348+ }
2349+
2350+ fn subspace_with_current < T : TuplePack > ( & self , t : & T ) -> Option < Subspace > {
2351+ match self . directory_stack . get ( self . directory_index ) {
2352+ None => None ,
2353+ Some ( directory_or_subspace) => match directory_or_subspace {
2354+ DirectoryStackItem :: DirectorySubspace ( d) => Some ( d. subspace ( t) ) ,
2355+ DirectoryStackItem :: Subspace ( d) => Some ( d. subspace ( t) ) ,
2356+ _ => None ,
2357+ } ,
2358+ }
2359+ }
2360+
2361+ fn get_current_directory_subspace ( & self ) -> Option < DirectorySubspace > {
2362+ debug ! ( "current directory is at index {}" , self . directory_index) ;
2363+ match self . directory_stack . get ( self . directory_index ) {
2364+ None => None ,
2365+ Some ( directory_or_subspace) => match directory_or_subspace {
2366+ DirectoryStackItem :: DirectorySubspace ( d) => Some ( d. clone ( ) ) ,
2367+ _ => None ,
2368+ } ,
2369+ }
2370+ }
22242371}
22252372
22262373fn main ( ) {
0 commit comments