@@ -27,14 +27,18 @@ static GOT_COMMITTED_VERSION: Element =
27
27
static ERROR_NONE : Element = Element :: Bytes ( Bytes ( Cow :: Borrowed ( b"ERROR: NONE" ) ) ) ;
28
28
static ERROR_MULTIPLE : Element = Element :: Bytes ( Bytes ( Cow :: Borrowed ( b"ERROR: MULTIPLE" ) ) ) ;
29
29
static OK : Element = Element :: Bytes ( Bytes ( Cow :: Borrowed ( b"OK" ) ) ) ;
30
+ static ERROR_DIRECTORY : Element = Element :: Bytes ( Bytes ( Cow :: Borrowed ( b"DIRECTORY_ERROR" ) ) ) ;
30
31
31
32
#[ cfg( feature = "fdb-6_2" ) ]
32
33
static GOT_APPROXIMATE_SIZE : Element =
33
34
Element :: Bytes ( Bytes ( Cow :: Borrowed ( b"GOT_APPROXIMATE_SIZE" ) ) ) ;
34
35
35
36
use crate :: fdb:: options:: { MutationType , StreamingMode } ;
36
37
37
- use foundationdb:: directory:: DirectoryLayer ;
38
+ use foundationdb:: directory:: directory_layer:: DirectoryLayer ;
39
+ use foundationdb:: directory:: directory_subspace:: DirectorySubspace ;
40
+ use foundationdb:: directory:: error:: DirectoryError ;
41
+ use foundationdb:: directory:: Directory ;
38
42
use tuple:: VersionstampOffset ;
39
43
40
44
fn mutation_from_str ( s : & str ) -> MutationType {
@@ -101,6 +105,7 @@ impl std::fmt::Debug for Instr {
101
105
#[ derive( Debug ) ]
102
106
enum DirectoryStackItem {
103
107
Directory ( DirectoryLayer ) ,
108
+ DirectorySubspace ( DirectorySubspace ) ,
104
109
Subspace ( Subspace ) ,
105
110
Null ,
106
111
}
@@ -701,6 +706,27 @@ impl StackMachine {
701
706
}
702
707
}
703
708
709
+ fn push_directory_err ( & mut self , code : InstrCode , number : usize , err : DirectoryError ) {
710
+ debug ! ( "DIRECTORY_ERROR during {:?}: {:?}" , code, err) ;
711
+ let packed = pack ( & ( ERROR_DIRECTORY ) ) ;
712
+ self . push ( number, Element :: Bytes ( packed. into ( ) ) ) ;
713
+
714
+ if let InstrCode :: DirectoryCreateSubspace
715
+ | InstrCode :: DirectoryCreateLayer
716
+ | InstrCode :: DirectoryCreate
717
+ | InstrCode :: DirectoryOpen
718
+ | InstrCode :: DirectoryMove
719
+ | InstrCode :: DirectoryMoveTo
720
+ | InstrCode :: DirectoryOpenSubspace = code
721
+ {
722
+ debug ! (
723
+ "pushed NULL in the directory_stack at index {} because of an error" ,
724
+ self . directory_stack. len( )
725
+ ) ;
726
+ self . directory_stack . push ( DirectoryStackItem :: Null ) ;
727
+ }
728
+ }
729
+
704
730
fn push_err ( & mut self , number : usize , err : FdbError ) {
705
731
trace ! ( "ERROR {:?}" , err) ;
706
732
let packed = pack ( & Element :: Tuple ( vec ! [
@@ -1614,6 +1640,11 @@ impl StackMachine {
1614
1640
let raw_prefix = self . pop_bytes ( ) . await ;
1615
1641
let subspace =
1616
1642
Subspace :: from_bytes ( & raw_prefix) . subspace ( tuple_prefix. get ( 0 ) . unwrap ( ) ) ;
1643
+ debug ! (
1644
+ "pushing {:?} at index {}" ,
1645
+ & subspace,
1646
+ self . directory_stack. len( )
1647
+ ) ;
1617
1648
self . directory_stack
1618
1649
. push ( DirectoryStackItem :: Subspace ( subspace) ) ;
1619
1650
debug ! ( "directory_stack: {:?}" , self . directory_stack) ;
@@ -1663,14 +1694,13 @@ impl StackMachine {
1663
1694
1664
1695
debug ! ( "pushed a directory at index {}" , self . directory_stack. len( ) ) ;
1665
1696
1666
- self . directory_stack . push ( DirectoryStackItem :: Directory (
1667
- directory :: DirectoryLayer {
1697
+ self . directory_stack
1698
+ . push ( DirectoryStackItem :: Directory ( DirectoryLayer {
1668
1699
node_subspace,
1669
1700
content_subspace,
1670
1701
allow_manual_prefix,
1671
1702
..Default :: default ( )
1672
- } ,
1673
- ) ) ;
1703
+ } ) ) ;
1674
1704
}
1675
1705
}
1676
1706
@@ -1708,9 +1738,7 @@ impl StackMachine {
1708
1738
}
1709
1739
} ;
1710
1740
1711
- dbg ! ( & prefix) ;
1712
-
1713
- let subspace = match directory
1741
+ let directory_subspace = match directory
1714
1742
. create (
1715
1743
txn,
1716
1744
( * path. get ( 0 ) . unwrap ( ) . to_owned ( ) ) . to_vec ( ) ,
@@ -1725,8 +1753,13 @@ impl StackMachine {
1725
1753
}
1726
1754
} ;
1727
1755
1756
+ debug ! (
1757
+ "pushing created {:?} at index {}" ,
1758
+ & directory_subspace,
1759
+ self . directory_stack. len( )
1760
+ ) ;
1728
1761
self . directory_stack
1729
- . push ( DirectoryStackItem :: Subspace ( subspace ) ) ;
1762
+ . push ( DirectoryStackItem :: DirectorySubspace ( directory_subspace ) ) ;
1730
1763
}
1731
1764
1732
1765
DirectoryOpen => {
@@ -1752,18 +1785,24 @@ impl StackMachine {
1752
1785
}
1753
1786
} ;
1754
1787
1755
- let subspace = match directory
1788
+ let directory_subspace = match directory
1756
1789
. open ( txn, ( * path. get ( 0 ) . unwrap ( ) . to_owned ( ) ) . to_vec ( ) , layer)
1757
1790
. await
1758
1791
{
1759
1792
Ok ( s) => s,
1760
1793
Err ( e) => {
1761
- panic ! ( "could not call directory.create: {:?}" , e) ;
1794
+ self . push_directory_err ( instr. code , number, e) ;
1795
+ return Err ( ( ) ) ;
1762
1796
}
1763
1797
} ;
1764
1798
1799
+ debug ! (
1800
+ "pushing newly opened {:?} at index {}" ,
1801
+ & directory_subspace,
1802
+ self . directory_stack. len( )
1803
+ ) ;
1765
1804
self . directory_stack
1766
- . push ( DirectoryStackItem :: Subspace ( subspace ) ) ;
1805
+ . push ( DirectoryStackItem :: DirectorySubspace ( directory_subspace ) ) ;
1767
1806
}
1768
1807
1769
1808
// Use the current directory for this operation.
@@ -1794,7 +1833,7 @@ impl StackMachine {
1794
1833
}
1795
1834
} ;
1796
1835
1797
- let subspace = match directory
1836
+ let directory_subspace = match directory
1798
1837
. create_or_open (
1799
1838
txn,
1800
1839
( * path. get ( 0 ) . unwrap ( ) . to_owned ( ) ) . to_vec ( ) ,
@@ -1809,8 +1848,13 @@ impl StackMachine {
1809
1848
}
1810
1849
} ;
1811
1850
1851
+ debug ! (
1852
+ "pushing created_or_opened {:?} at index {}" ,
1853
+ & directory_subspace,
1854
+ self . directory_stack. len( )
1855
+ ) ;
1812
1856
self . directory_stack
1813
- . push ( DirectoryStackItem :: Subspace ( subspace ) ) ;
1857
+ . push ( DirectoryStackItem :: DirectorySubspace ( directory_subspace ) ) ;
1814
1858
}
1815
1859
1816
1860
// Pop the top item off the stack as [index]. Set the current directory list
@@ -1927,7 +1971,6 @@ impl StackMachine {
1927
1971
// tuple off the stack as [path]. Call list, passing it path if one was popped.
1928
1972
// Pack the resulting list of directories using the tuple layer and push the
1929
1973
// packed string onto the stack.
1930
- // TODO(PZ): fix seed 3110103296
1931
1974
DirectoryList => {
1932
1975
debug ! ( "List stack: {:?}" , self . stack) ;
1933
1976
let count = self . pop_usize ( ) . await ;
@@ -1946,20 +1989,55 @@ impl StackMachine {
1946
1989
1947
1990
let paths = paths. get ( 0 ) . expect ( "could not retrieve a path" ) ;
1948
1991
1949
- directory
1950
- . list ( txn, paths. to_vec ( ) )
1951
- . await
1952
- . expect ( "could not list directory" )
1953
- . iter ( )
1954
- . for_each ( |s| self . push ( number, Element :: String ( Cow :: Owned ( s. clone ( ) ) ) ) ) ;
1992
+ let children = match directory. list ( txn, paths. to_vec ( ) ) . await {
1993
+ Ok ( v) => v,
1994
+ Err ( e) => {
1995
+ self . push_directory_err ( instr. code , number, e) ;
1996
+ return Err ( ( ) ) ;
1997
+ }
1998
+ } ;
1999
+
2000
+ let mut elements: Vec < Element > = vec ! [ ] ;
2001
+ for child in children {
2002
+ let element = Element :: String ( Cow :: from ( child) ) ;
2003
+ elements. push ( element) ;
2004
+ }
2005
+ let tuple = Element :: Tuple ( elements) ;
2006
+ self . push ( number, Element :: Bytes ( pack ( & tuple) . into ( ) ) ) ;
1955
2007
}
1956
2008
1957
2009
// Use the current directory for this operation.
1958
2010
//
1959
2011
// Pop 1 item off the stack as [count] (either 0 or 1). If count is 1, pop 1
1960
2012
// tuple off the stack as [path]. Call exists, passing it path if one
1961
2013
// was popped. Push 1 onto the stack if the path exists and 0 if it does not.
1962
- DirectoryExists => unimplemented ! ( ) ,
2014
+ DirectoryExists => {
2015
+ debug ! ( "Exists stack: {:?}" , self . stack) ;
2016
+ let count = self . pop_usize ( ) . await ;
2017
+
2018
+ let paths = self . pop_tuple ( count) . await ;
2019
+
2020
+ let directory = self
2021
+ . get_current_directory ( )
2022
+ . expect ( "could not find a directory" ) ;
2023
+
2024
+ let txn = match trx {
2025
+ TransactionState :: Transaction ( ref t) => t,
2026
+ _ => {
2027
+ panic ! ( "could not find an active transaction" ) ;
2028
+ }
2029
+ } ;
2030
+
2031
+ let paths = paths. get ( 0 ) . expect ( "could not retrieve a path" ) ;
2032
+ let exists = match directory. exists ( txn, paths. to_owned ( ) ) . await {
2033
+ Ok ( exist) => exist,
2034
+ Err ( e) => {
2035
+ self . push_directory_err ( instr. code , number, e) ;
2036
+ return Err ( ( ) ) ;
2037
+ }
2038
+ } ;
2039
+ self . push ( number, Element :: Int ( i64:: from ( exists) ) ) ;
2040
+ }
1963
2041
1964
2042
// Use the current directory for this operation.
1965
2043
//
@@ -2064,16 +2142,15 @@ impl StackMachine {
2064
2142
handle. join ( ) . expect ( "joined thread to not panic" ) ;
2065
2143
}
2066
2144
}
2067
- fn get_current_directory ( & self ) -> Option < & DirectoryLayer > {
2145
+ fn get_current_directory ( & self ) -> Option < Box < dyn Directory > > {
2146
+ debug ! ( "current directory is at index {}" , self . directory_index) ;
2068
2147
match self . directory_stack . get ( self . directory_index ) {
2069
2148
None => None ,
2070
- Some ( directory_or_subspace) => {
2071
- dbg ! ( directory_or_subspace) ;
2072
- match directory_or_subspace {
2073
- DirectoryStackItem :: Directory ( d) => Some ( d) ,
2074
- _ => None ,
2075
- }
2076
- }
2149
+ Some ( directory_or_subspace) => match directory_or_subspace {
2150
+ DirectoryStackItem :: Directory ( d) => Some ( Box :: new ( d. clone ( ) ) ) ,
2151
+ DirectoryStackItem :: DirectorySubspace ( d) => Some ( Box :: new ( ( * d) . clone ( ) ) ) ,
2152
+ _ => None ,
2153
+ } ,
2077
2154
}
2078
2155
}
2079
2156
}
0 commit comments