@@ -39,6 +39,8 @@ use foundationdb::directory::directory_layer::DirectoryLayer;
39
39
use foundationdb:: directory:: directory_subspace:: DirectorySubspace ;
40
40
use foundationdb:: directory:: error:: DirectoryError ;
41
41
use foundationdb:: directory:: Directory ;
42
+ use foundationdb:: tuple:: { PackResult , TupleUnpack } ;
43
+
42
44
use tuple:: VersionstampOffset ;
43
45
44
46
fn mutation_from_str ( s : & str ) -> MutationType {
@@ -644,11 +646,12 @@ impl StackMachine {
644
646
let element = self . pop_element ( ) . await ;
645
647
match element {
646
648
Element :: Bytes ( v) => v,
649
+ Element :: Nil => Bytes :: from ( vec ! [ ] ) ,
647
650
_ => panic ! ( "bytes were expected, found {:?}" , element) ,
648
651
}
649
652
}
650
653
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 > > {
652
655
let mut result = vec ! [ ] ;
653
656
654
657
if count == 0 {
@@ -1636,7 +1639,7 @@ impl StackMachine {
1636
1639
// raw_prefix. Append it to the directory list.
1637
1640
DirectoryCreateSubspace => {
1638
1641
debug ! ( "CreateSubspace stack: {:?}" , self . stack) ;
1639
- let tuple_prefix = self . pop_tuple ( 1 ) . await ;
1642
+ let tuple_prefix = self . pop_string_tuple ( 1 ) . await ;
1640
1643
let raw_prefix = self . pop_bytes ( ) . await ;
1641
1644
let subspace =
1642
1645
Subspace :: from_bytes ( & raw_prefix) . subspace ( tuple_prefix. get ( 0 ) . unwrap ( ) ) ;
@@ -1711,7 +1714,7 @@ impl StackMachine {
1711
1714
DirectoryCreate => {
1712
1715
debug ! ( "Create stack: {:?}" , self . stack) ;
1713
1716
1714
- let path = self . pop_tuple ( 1 ) . await ;
1717
+ let path = self . pop_string_tuple ( 1 ) . await ;
1715
1718
let bytes_layer = self . pop_bytes ( ) . await ;
1716
1719
let bytes_prefix = self . pop_bytes ( ) . await ;
1717
1720
@@ -1728,7 +1731,7 @@ impl StackMachine {
1728
1731
} ;
1729
1732
1730
1733
let directory = self
1731
- . get_current_directory ( )
1734
+ . get_current_directory_layer ( )
1732
1735
. expect ( "could not find a directory" ) ;
1733
1736
1734
1737
let txn = match trx {
@@ -1765,7 +1768,7 @@ impl StackMachine {
1765
1768
DirectoryOpen => {
1766
1769
debug ! ( "DirectoryOpen stack: {:?}" , self . stack) ;
1767
1770
1768
- let path = self . pop_tuple ( 1 ) . await ;
1771
+ let path = self . pop_string_tuple ( 1 ) . await ;
1769
1772
let bytes_layer = self . pop_bytes ( ) . await ;
1770
1773
1771
1774
let layer = if bytes_layer. is_empty ( ) {
@@ -1775,7 +1778,7 @@ impl StackMachine {
1775
1778
} ;
1776
1779
1777
1780
let directory = self
1778
- . get_current_directory ( )
1781
+ . get_current_directory_layer ( )
1779
1782
. expect ( "could not find a directory" ) ;
1780
1783
1781
1784
let txn = match trx {
@@ -1812,7 +1815,7 @@ impl StackMachine {
1812
1815
DirectoryCreateOrOpen => {
1813
1816
debug ! ( "CreateOrOpen stack: {:?}" , self . stack) ;
1814
1817
1815
- let path = self . pop_tuple ( 1 ) . await ;
1818
+ let path = self . pop_string_tuple ( 1 ) . await ;
1816
1819
let bytes_layer = self . pop_bytes ( ) . await ;
1817
1820
1818
1821
let layer = if bytes_layer. is_empty ( ) {
@@ -1822,7 +1825,7 @@ impl StackMachine {
1822
1825
} ;
1823
1826
1824
1827
let directory = self
1825
- . get_current_directory ( )
1828
+ . get_current_directory_layer ( )
1826
1829
. expect ( "could not find a directory" ) ;
1827
1830
1828
1831
let txn = match trx {
@@ -1900,10 +1903,10 @@ impl StackMachine {
1900
1903
DirectoryMove => {
1901
1904
debug ! ( "Move stack: {:?}" , self . stack) ;
1902
1905
1903
- let paths = self . pop_tuple ( 2 ) . await ;
1906
+ let paths = self . pop_string_tuple ( 2 ) . await ;
1904
1907
1905
1908
let directory = self
1906
- . get_current_directory ( )
1909
+ . get_current_directory_layer ( )
1907
1910
. expect ( "could not find a directory" ) ;
1908
1911
1909
1912
let txn = match trx {
@@ -1913,6 +1916,8 @@ impl StackMachine {
1913
1916
}
1914
1917
} ;
1915
1918
1919
+ debug ! ( "starting" ) ;
1920
+
1916
1921
match directory
1917
1922
. move_to (
1918
1923
txn,
@@ -1934,6 +1939,7 @@ impl StackMachine {
1934
1939
self . push_directory_err ( & instr. code , number, e) ;
1935
1940
}
1936
1941
} ;
1942
+ debug ! ( "finished" ) ;
1937
1943
}
1938
1944
1939
1945
// Use the current directory for this operation.
@@ -1943,10 +1949,10 @@ impl StackMachine {
1943
1949
DirectoryMoveTo => {
1944
1950
debug ! ( "MoveTo stack: {:?}" , self . stack) ;
1945
1951
1946
- let paths = self . pop_tuple ( 1 ) . await ;
1952
+ let paths = self . pop_string_tuple ( 1 ) . await ;
1947
1953
1948
1954
let directory = self
1949
- . get_current_directory ( )
1955
+ . get_current_directory_layer ( )
1950
1956
. expect ( "could not find a directory" ) ;
1951
1957
1952
1958
let txn = match trx {
@@ -1983,10 +1989,10 @@ impl StackMachine {
1983
1989
DirectoryRemove => {
1984
1990
debug ! ( "Remove stack: {:?}" , self . stack) ;
1985
1991
let count = self . pop_usize ( ) . await ;
1986
- let paths = self . pop_tuple ( count) . await ;
1992
+ let paths = self . pop_string_tuple ( count) . await ;
1987
1993
1988
1994
let directory = self
1989
- . get_current_directory ( )
1995
+ . get_current_directory_layer ( )
1990
1996
. expect ( "could not find a directory" ) ;
1991
1997
1992
1998
let txn = match trx {
@@ -2011,10 +2017,10 @@ impl StackMachine {
2011
2017
DirectoryRemoveIfExists => {
2012
2018
debug ! ( "RemoveIfExists stack: {:?}" , self . stack) ;
2013
2019
let count = self . pop_usize ( ) . await ;
2014
- let paths = self . pop_tuple ( count) . await ;
2020
+ let paths = self . pop_string_tuple ( count) . await ;
2015
2021
2016
2022
let directory = self
2017
- . get_current_directory ( )
2023
+ . get_current_directory_layer ( )
2018
2024
. expect ( "could not find a directory" ) ;
2019
2025
2020
2026
let txn = match trx {
@@ -2030,7 +2036,10 @@ impl StackMachine {
2030
2036
. await
2031
2037
. expect ( "could not check of existence" )
2032
2038
{
2033
- directory. remove ( txn, paths. to_owned ( ) ) . await ;
2039
+ directory
2040
+ . remove ( txn, paths. to_owned ( ) )
2041
+ . await
2042
+ . expect ( "could not remove path" ) ;
2034
2043
}
2035
2044
}
2036
2045
@@ -2043,10 +2052,10 @@ impl StackMachine {
2043
2052
DirectoryList => {
2044
2053
debug ! ( "List stack: {:?}" , self . stack) ;
2045
2054
let count = self . pop_usize ( ) . await ;
2046
- let paths = self . pop_tuple ( count) . await ;
2055
+ let paths = self . pop_string_tuple ( count) . await ;
2047
2056
2048
2057
let directory = self
2049
- . get_current_directory ( )
2058
+ . get_current_directory_layer ( )
2050
2059
. expect ( "could not find a directory" ) ;
2051
2060
2052
2061
let txn = match trx {
@@ -2083,10 +2092,10 @@ impl StackMachine {
2083
2092
debug ! ( "Exists stack: {:?}" , self . stack) ;
2084
2093
let count = self . pop_usize ( ) . await ;
2085
2094
2086
- let paths = self . pop_tuple ( count) . await ;
2095
+ let paths = self . pop_string_tuple ( count) . await ;
2087
2096
2088
2097
let directory = self
2089
- . get_current_directory ( )
2098
+ . get_current_directory_layer ( )
2090
2099
. expect ( "could not find a directory" ) ;
2091
2100
2092
2101
let txn = match trx {
@@ -2111,19 +2120,58 @@ impl StackMachine {
2111
2120
//
2112
2121
// Pop 1 tuple off the stack as [key_tuple]. Pack key_tuple and push the result
2113
2122
// 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
+ }
2115
2139
2116
2140
// Use the current directory for this operation.
2117
2141
//
2118
2142
// Pop 1 item off the stack as [key]. Unpack key and push the resulting tuple
2119
2143
// 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
+ }
2121
2153
2122
2154
// Use the current directory for this operation.
2123
2155
//
2124
2156
// Pop 1 tuple off the stack as [tuple]. Create a range using tuple and push
2125
2157
// 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
+ }
2127
2175
2128
2176
// Use the current directory for this operation.
2129
2177
//
@@ -2142,7 +2190,21 @@ impl StackMachine {
2142
2190
// Pop 1 item off the stack as [prefix]. Let key equal
2143
2191
// prefix + tuple.pack([dir_index]). Set key to be the result of calling
2144
2192
// 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
+ }
2146
2208
2147
2209
// Use the current directory for this operation.
2148
2210
//
@@ -2161,7 +2223,45 @@ impl StackMachine {
2161
2223
//
2162
2224
// Where log_subspace[u<str>] is the subspace packed tuple containing only the
2163
2225
// 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
+ }
2165
2265
2166
2266
// Use the current directory for this operation.
2167
2267
//
@@ -2210,7 +2310,7 @@ impl StackMachine {
2210
2310
handle. join ( ) . expect ( "joined thread to not panic" ) ;
2211
2311
}
2212
2312
}
2213
- fn get_current_directory ( & self ) -> Option < Box < dyn Directory > > {
2313
+ fn get_current_directory_layer ( & self ) -> Option < Box < dyn Directory > > {
2214
2314
debug ! ( "current directory is at index {}" , self . directory_index) ;
2215
2315
match self . directory_stack . get ( self . directory_index ) {
2216
2316
None => None ,
@@ -2221,6 +2321,53 @@ impl StackMachine {
2221
2321
} ,
2222
2322
}
2223
2323
}
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
+ }
2224
2371
}
2225
2372
2226
2373
fn main ( ) {
0 commit comments