1616// under the License.
1717
1818//! it's a modified version of hdfs-rs
19- use std:: collections:: HashMap ;
19+ use std:: collections:: { HashMap , HashSet } ;
2020use std:: ffi:: { CStr , CString } ;
2121use std:: fmt:: Write ;
2222use std:: fmt:: { Debug , Formatter } ;
@@ -52,6 +52,14 @@ pub fn get_hdfs() -> Result<Arc<HdfsFs>, HdfsErr> {
5252 HDFS_MANAGER . get_hdfs_by_full_path ( "default" )
5353}
5454
55+ /// Register the name of a new scheme that this implementation should allow. No validation is done.
56+ pub fn register_scheme ( scheme : & ' static str ) {
57+ HDFS_MANAGER . register_scheme ( scheme)
58+ }
59+ pub fn get_registered_schemes ( ) -> HashSet < & ' static str > {
60+ HDFS_MANAGER . hdfs_schemes . read ( ) . unwrap ( ) . clone ( )
61+ }
62+
5563/// Remove an instance of HdfsFs from the cache by a specified path with uri
5664pub fn unload_hdfs_cache_by_full_path (
5765 path : & str ,
@@ -64,16 +72,23 @@ pub fn unload_hdfs_cache(hdfs: Arc<HdfsFs>) -> Result<Option<Arc<HdfsFs>>, HdfsE
6472 HDFS_MANAGER . remove_hdfs ( hdfs)
6573}
6674
75+
76+ pub const LOCAL_FS_SCHEME : & str = "file" ;
77+ pub const HDFS_FS_SCHEME : & str = "hdfs" ;
78+ pub const VIEW_FS_SCHEME : & str = "viewfs" ;
79+ pub const initial_schemes: [ & str ; 3 ] = [ LOCAL_FS_SCHEME , HDFS_FS_SCHEME , VIEW_FS_SCHEME ] ;
6780/// Hdfs manager
6881/// All of the HdfsFs instances will be managed in a singleton HdfsManager
6982struct HdfsManager {
7083 hdfs_cache : Arc < RwLock < HashMap < String , Arc < HdfsFs > > > > ,
84+ hdfs_schemes : Arc < RwLock < HashSet < & ' static str > > > ,
7185}
7286
7387impl HdfsManager {
7488 fn new ( ) -> Self {
7589 Self {
7690 hdfs_cache : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
91+ hdfs_schemes : Arc :: new ( RwLock :: new ( initial_schemes. into_iter ( ) . collect ( ) ) )
7792 }
7893 }
7994
@@ -140,6 +155,12 @@ impl HdfsManager {
140155 let mut cache = self . hdfs_cache . write ( ) . unwrap ( ) ;
141156 Ok ( cache. remove ( hdfs_key) )
142157 }
158+ fn register_scheme ( & self , scheme : & ' static str ) {
159+ let mut hdfs_schemes = self . hdfs_schemes . write ( ) . unwrap ( ) ;
160+ if !hdfs_schemes. contains ( scheme) {
161+ hdfs_schemes. insert ( scheme) ;
162+ }
163+ }
143164}
144165
145166/// Hdfs Filesystem
@@ -838,20 +859,16 @@ impl Drop for BlockHosts {
838859 }
839860}
840861
841- pub const LOCAL_FS_SCHEME : & str = "file" ;
842- pub const HDFS_FS_SCHEME : & str = "hdfs" ;
843- pub const VIEW_FS_SCHEME : & str = "viewfs" ;
844-
845862#[ inline]
846863fn get_namenode_uri ( path : & str ) -> Result < String , HdfsErr > {
864+ let schemes = HDFS_MANAGER . hdfs_schemes . read ( ) . unwrap ( ) ;
847865 match Url :: parse ( path) {
848866 Ok ( url) => match url. scheme ( ) {
849867 LOCAL_FS_SCHEME => Ok ( "file:///" . to_string ( ) ) ,
850- HDFS_FS_SCHEME | VIEW_FS_SCHEME => {
868+ scheme if schemes . contains ( & scheme ) => {
851869 if let Some ( host) = url. host ( ) {
852870 let mut uri_builder = String :: new ( ) ;
853871 write ! ( & mut uri_builder, "{}://{}" , url. scheme( ) , host) . unwrap ( ) ;
854-
855872 if let Some ( port) = url. port ( ) {
856873 write ! ( & mut uri_builder, ":{}" , port) . unwrap ( ) ;
857874 }
@@ -860,22 +877,25 @@ fn get_namenode_uri(path: &str) -> Result<String, HdfsErr> {
860877 Err ( HdfsErr :: InvalidUrl ( path. to_string ( ) ) )
861878 }
862879 }
863- _ => Err ( HdfsErr :: InvalidUrl ( path. to_string ( ) ) ) ,
880+ _ => {
881+ Err ( HdfsErr :: InvalidUrl ( path. to_string ( ) ) )
882+ }
864883 } ,
865884 Err ( _) => Err ( HdfsErr :: InvalidUrl ( path. to_string ( ) ) ) ,
866885 }
867886}
868887
869888#[ inline]
870889pub fn get_uri ( path : & str ) -> Result < String , HdfsErr > {
890+ let schemes = HDFS_MANAGER . hdfs_schemes . read ( ) . unwrap ( ) ;
871891 let path = if path. starts_with ( '/' ) {
872892 format ! ( "{}://{}" , LOCAL_FS_SCHEME , path)
873893 } else {
874894 path. to_string ( )
875895 } ;
876896 match Url :: parse ( & path) {
877897 Ok ( url) => match url. scheme ( ) {
878- LOCAL_FS_SCHEME | HDFS_FS_SCHEME | VIEW_FS_SCHEME => Ok ( url. to_string ( ) ) ,
898+ scheme if schemes . contains ( & scheme ) => Ok ( url. to_string ( ) ) ,
879899 _ => Err ( HdfsErr :: InvalidUrl ( path. to_string ( ) ) ) ,
880900 } ,
881901 Err ( _) => Err ( HdfsErr :: InvalidUrl ( path. to_string ( ) ) ) ,
0 commit comments