@anysphere/file-service 0.0.0-a4fe55c1 → 0.0.0-ac774178
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -6
- package/package.json +7 -7
- package/src/lib.rs +55 -148
- package/src/merkle_tree/local_construction.rs +16 -21
- package/src/merkle_tree/mod.rs +123 -299
package/index.d.ts
CHANGED
|
@@ -6,15 +6,10 @@
|
|
|
6
6
|
export class MerkleClient {
|
|
7
7
|
constructor(rootDirectory: string)
|
|
8
8
|
init(): Promise<void>
|
|
9
|
-
computeMerkleTree(): Promise<void>
|
|
10
9
|
updateFile(filePath: string): Promise<void>
|
|
11
10
|
deleteFile(filePath: string): Promise<void>
|
|
12
|
-
getSubtreeHash(
|
|
11
|
+
getSubtreeHash(path: string): Promise<string>
|
|
13
12
|
getNumEmbeddableFiles(): Promise<number>
|
|
14
13
|
getAllFiles(): Promise<Array<string>>
|
|
15
|
-
getAllDirFilesToEmbed(absoluteFilePath: string): Promise<Array<string>>
|
|
16
|
-
getNextFileToEmbed(): Promise<Array<string>>
|
|
17
|
-
getSpline(absoluteFilePath: string): Promise<Array<string>>
|
|
18
14
|
getHashesForFiles(files: Array<string>): Promise<Array<string>>
|
|
19
|
-
updateRootDirectory(rootDirectory: string): void
|
|
20
15
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anysphere/file-service",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-ac774178",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"types": "index.d.ts",
|
|
6
6
|
"napi": {
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"version": "napi version"
|
|
36
36
|
},
|
|
37
37
|
"optionalDependencies": {
|
|
38
|
-
"@anysphere/file-service-win32-x64-msvc": "0.0.0-
|
|
39
|
-
"@anysphere/file-service-darwin-x64": "0.0.0-
|
|
40
|
-
"@anysphere/file-service-linux-x64-gnu": "0.0.0-
|
|
41
|
-
"@anysphere/file-service-darwin-arm64": "0.0.0-
|
|
42
|
-
"@anysphere/file-service-win32-arm64-msvc": "0.0.0-
|
|
43
|
-
"@anysphere/file-service-darwin-universal": "0.0.0-
|
|
38
|
+
"@anysphere/file-service-win32-x64-msvc": "0.0.0-ac774178",
|
|
39
|
+
"@anysphere/file-service-darwin-x64": "0.0.0-ac774178",
|
|
40
|
+
"@anysphere/file-service-linux-x64-gnu": "0.0.0-ac774178",
|
|
41
|
+
"@anysphere/file-service-darwin-arm64": "0.0.0-ac774178",
|
|
42
|
+
"@anysphere/file-service-win32-arm64-msvc": "0.0.0-ac774178",
|
|
43
|
+
"@anysphere/file-service-darwin-universal": "0.0.0-ac774178"
|
|
44
44
|
}
|
|
45
45
|
}
|
package/src/lib.rs
CHANGED
|
@@ -3,8 +3,6 @@ pub mod file_utils;
|
|
|
3
3
|
pub mod git_utils;
|
|
4
4
|
pub mod merkle_tree;
|
|
5
5
|
|
|
6
|
-
use std::vec;
|
|
7
|
-
|
|
8
6
|
use merkle_tree::{LocalConstruction, MerkleTree};
|
|
9
7
|
|
|
10
8
|
#[macro_use]
|
|
@@ -33,14 +31,14 @@ impl MerkleClient {
|
|
|
33
31
|
// 3. sync with the remote
|
|
34
32
|
self.compute_merkle_tree().await?;
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
Ok(())
|
|
37
35
|
}
|
|
38
36
|
|
|
39
37
|
pub async unsafe fn interrupt(&mut self) -> Result<(), napi::Error> {
|
|
40
38
|
unimplemented!("Interrupt is not implemented yet");
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
#[napi]
|
|
41
|
+
// #[napi]
|
|
44
42
|
pub async unsafe fn compute_merkle_tree(
|
|
45
43
|
&mut self,
|
|
46
44
|
) -> Result<(), napi::Error> {
|
|
@@ -69,150 +67,59 @@ impl MerkleClient {
|
|
|
69
67
|
let _r = self.tree.delete_file(file_path);
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
let files = self.tree.get_all_files().await;
|
|
126
|
-
|
|
127
|
-
match files {
|
|
128
|
-
Ok(files) => Ok(files),
|
|
129
|
-
Err(e) => Err(napi::Error::new(
|
|
130
|
-
napi::Status::Unknown,
|
|
131
|
-
format!("Error in get_all_files: {:?}", e),
|
|
132
|
-
)),
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
#[napi]
|
|
137
|
-
pub async fn get_all_dir_files_to_embed(
|
|
138
|
-
&self,
|
|
139
|
-
absolute_file_path: String,
|
|
140
|
-
) -> Result<Vec<String>, napi::Error> {
|
|
141
|
-
let absolute_path_str = absolute_file_path.as_str();
|
|
142
|
-
let files = self
|
|
143
|
-
.tree
|
|
144
|
-
.get_all_dir_files_to_embed(absolute_path_str)
|
|
145
|
-
.await;
|
|
146
|
-
|
|
147
|
-
match files {
|
|
148
|
-
Ok(files) => Ok(files),
|
|
149
|
-
Err(e) => Err(napi::Error::new(
|
|
150
|
-
napi::Status::Unknown,
|
|
151
|
-
format!("Error in get_all_dir_files_to_embed: {:?}", e),
|
|
152
|
-
)),
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
#[napi]
|
|
157
|
-
pub async unsafe fn get_next_file_to_embed(
|
|
158
|
-
&mut self,
|
|
159
|
-
) -> Result<Vec<String>, napi::Error> {
|
|
160
|
-
let n = self.tree.get_next_file_to_embed().await;
|
|
161
|
-
|
|
162
|
-
match n {
|
|
163
|
-
Ok((file, path)) => {
|
|
164
|
-
// now our job is to put the filename as the first element of the path.
|
|
165
|
-
|
|
166
|
-
// TODO(sualeh): we should assert that the path is ascending up to the path.
|
|
167
|
-
|
|
168
|
-
let ret = vec![file];
|
|
169
|
-
let ret = ret.into_iter().chain(path.into_iter()).collect::<Vec<_>>();
|
|
170
|
-
|
|
171
|
-
Ok(ret)
|
|
172
|
-
}
|
|
173
|
-
Err(e) => Err(napi::Error::new(
|
|
174
|
-
napi::Status::Unknown,
|
|
175
|
-
format!("Error in get_next_file_to_embed: {:?}", e),
|
|
176
|
-
)),
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// FIXME(sualeh): get_spline
|
|
181
|
-
#[napi]
|
|
182
|
-
pub async fn get_spline(
|
|
183
|
-
&self,
|
|
184
|
-
absolute_file_path: String,
|
|
185
|
-
) -> Result<Vec<String>, napi::Error> {
|
|
186
|
-
// let spline = self.tree.get_spline(absolute_file_path).await;
|
|
187
|
-
|
|
188
|
-
return Ok(vec![]);
|
|
189
|
-
|
|
190
|
-
// match spline {
|
|
191
|
-
// Ok(spline) => Ok(spline),
|
|
192
|
-
// Err(e) => Err(napi::Error::new(
|
|
193
|
-
// napi::Status::Unknown,
|
|
194
|
-
// format!("Error in get_spline: {:?}", e),
|
|
195
|
-
// )),
|
|
196
|
-
// }
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
#[napi]
|
|
200
|
-
pub async fn get_hashes_for_files(
|
|
201
|
-
&self,
|
|
202
|
-
files: Vec<String>,
|
|
203
|
-
) -> Result<Vec<String>, napi::Error> {
|
|
204
|
-
let hashes = self.tree.get_hashes_for_files(files).await;
|
|
205
|
-
|
|
206
|
-
match hashes {
|
|
207
|
-
Ok(hashes) => Ok(hashes),
|
|
208
|
-
Err(e) => Err(napi::Error::new(
|
|
209
|
-
napi::Status::Unknown,
|
|
210
|
-
format!("Error in get_hashes_for_files: {:?}", e),
|
|
211
|
-
)),
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
#[napi]
|
|
70
|
+
#[napi]
|
|
71
|
+
pub async fn get_subtree_hash(&self, path: String) -> Result<String, napi::Error> {
|
|
72
|
+
let hash = self.tree.get_subtree_hash(path).await;
|
|
73
|
+
|
|
74
|
+
match hash {
|
|
75
|
+
Ok(hash) => Ok(hash),
|
|
76
|
+
Err(e) => Err(napi::Error::new(
|
|
77
|
+
napi::Status::Unknown,
|
|
78
|
+
format!("Error in get_subtree_hash: {:?}", e),
|
|
79
|
+
)),
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#[napi]
|
|
84
|
+
pub async fn get_num_embeddable_files(&self) -> Result<i32, napi::Error> {
|
|
85
|
+
let num = self.tree.get_num_embeddable_files().await;
|
|
86
|
+
|
|
87
|
+
match num {
|
|
88
|
+
Ok(num) => Ok(num),
|
|
89
|
+
Err(e) => Err(napi::Error::new(
|
|
90
|
+
napi::Status::Unknown,
|
|
91
|
+
format!("Error in get_num_embeddable_files: {:?}", e),
|
|
92
|
+
)),
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
#[napi]
|
|
97
|
+
pub async fn get_all_files(&self) -> Result<Vec<String>, napi::Error> {
|
|
98
|
+
let files = self.tree.get_all_files().await;
|
|
99
|
+
|
|
100
|
+
match files {
|
|
101
|
+
Ok(files) => Ok(files),
|
|
102
|
+
Err(e) => Err(napi::Error::new(
|
|
103
|
+
napi::Status::Unknown,
|
|
104
|
+
format!("Error in get_all_files: {:?}", e),
|
|
105
|
+
)),
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#[napi]
|
|
110
|
+
pub async fn get_hashes_for_files(&self, files: Vec<String>) -> Result<Vec<String>, napi::Error> {
|
|
111
|
+
let hashes = self.tree.get_hashes_for_files(files).await;
|
|
112
|
+
|
|
113
|
+
match hashes {
|
|
114
|
+
Ok(hashes) => Ok(hashes),
|
|
115
|
+
Err(e) => Err(napi::Error::new(
|
|
116
|
+
napi::Status::Unknown,
|
|
117
|
+
format!("Error in get_hashes_for_files: {:?}", e),
|
|
118
|
+
)),
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// #[napi]
|
|
216
123
|
pub fn update_root_directory(&mut self, root_directory: String) {
|
|
217
124
|
self.root_directory = root_directory;
|
|
218
125
|
}
|
|
@@ -3,16 +3,13 @@ use crate::merkle_tree::{
|
|
|
3
3
|
};
|
|
4
4
|
|
|
5
5
|
use super::{LocalConstruction, MerkleTree};
|
|
6
|
-
use std::collections::BTreeMap;
|
|
7
6
|
use std::path::PathBuf;
|
|
8
7
|
use std::{collections::HashMap, path::Path, sync::Arc};
|
|
9
8
|
use tonic::async_trait;
|
|
10
9
|
|
|
11
10
|
#[async_trait]
|
|
12
11
|
impl LocalConstruction for MerkleTree {
|
|
13
|
-
async fn new(
|
|
14
|
-
root_directory: Option<String>,
|
|
15
|
-
) -> Result<MerkleTree, anyhow::Error> {
|
|
12
|
+
async fn new(root_directory: Option<String>) -> Result<MerkleTree, anyhow::Error> {
|
|
16
13
|
if let Some(root_directory) = root_directory {
|
|
17
14
|
let n = MerkleTree::construct_merkle_tree(root_directory).await;
|
|
18
15
|
return n;
|
|
@@ -28,9 +25,7 @@ impl LocalConstruction for MerkleTree {
|
|
|
28
25
|
/// 2. compute hash for each file
|
|
29
26
|
/// 3. construct merkle tree
|
|
30
27
|
/// 4. return merkle tree
|
|
31
|
-
async fn construct_merkle_tree(
|
|
32
|
-
root_directory: String,
|
|
33
|
-
) -> Result<MerkleTree, anyhow::Error> {
|
|
28
|
+
async fn construct_merkle_tree(root_directory: String) -> Result<MerkleTree, anyhow::Error> {
|
|
34
29
|
let path = PathBuf::from(root_directory.clone());
|
|
35
30
|
if !path.exists() {
|
|
36
31
|
// FIXME: we should report this via a good logger.
|
|
@@ -40,23 +35,22 @@ impl LocalConstruction for MerkleTree {
|
|
|
40
35
|
let root_node = MerkleNode::new(path, None).await;
|
|
41
36
|
let mut mt = MerkleTree {
|
|
42
37
|
root: root_node,
|
|
43
|
-
files:
|
|
38
|
+
files: HashMap::new(),
|
|
44
39
|
root_path: root_directory,
|
|
45
|
-
cursor: None,
|
|
46
40
|
};
|
|
47
41
|
|
|
48
42
|
// we now iterate over all the nodes and add them to the hashmap
|
|
49
43
|
// TODO(later): i can make this parallel.
|
|
50
44
|
fn add_nodes_to_hashmap<'a>(
|
|
51
45
|
node: &'a MerkleNodePtr,
|
|
52
|
-
files: &'a mut
|
|
46
|
+
files: &'a mut HashMap<String, File>,
|
|
53
47
|
) -> PinnedFuture<'a, ()> {
|
|
54
48
|
Box::pin(async move {
|
|
55
49
|
let node_reader = node.read().await;
|
|
56
50
|
match &node_reader.node_type {
|
|
57
51
|
NodeType::Branch(n) => {
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
let children = &n.1;
|
|
53
|
+
files.insert(n.0.clone(), File { node: node.clone() });
|
|
60
54
|
for child in children {
|
|
61
55
|
add_nodes_to_hashmap(child, files).await;
|
|
62
56
|
}
|
|
@@ -108,9 +102,9 @@ impl LocalConstruction for MerkleTree {
|
|
|
108
102
|
// File does not exist in the tree, let's add it.
|
|
109
103
|
let e = self.attach_new_node_to_tree(file_path.clone()).await;
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
if e.is_err() {
|
|
106
|
+
return Err(anyhow::anyhow!("Could not attach new node to tree!"));
|
|
107
|
+
}
|
|
114
108
|
}
|
|
115
109
|
|
|
116
110
|
Ok(())
|
|
@@ -145,17 +139,18 @@ impl LocalConstruction for MerkleTree {
|
|
|
145
139
|
let parent_node = parent_node.unwrap();
|
|
146
140
|
let mut mut_parent = parent_node.write().await;
|
|
147
141
|
|
|
148
|
-
// BUG(sualeh): need to actually drop everything that is a child here.
|
|
149
|
-
// idea: enumerate all nodes that are children of this through a starts with query on the hashtable.
|
|
150
|
-
// then drop all of them.
|
|
151
|
-
// in opposite order of length.
|
|
152
142
|
|
|
153
|
-
|
|
143
|
+
// BUG(sualeh): need to actually drop everything that is a child here.
|
|
144
|
+
// idea: enumerate all nodes that are children of this through a starts with query on the hashtable.
|
|
145
|
+
// then drop all of them.
|
|
146
|
+
// in opposite order of length.
|
|
147
|
+
|
|
148
|
+
// then remove the node from the parent and you are done
|
|
154
149
|
|
|
155
150
|
// Remove the child from the parent node
|
|
156
151
|
match mut_parent.node_type {
|
|
157
152
|
NodeType::Branch(ref mut node) => {
|
|
158
|
-
|
|
153
|
+
let children = &mut node.1;
|
|
159
154
|
let mut found = false;
|
|
160
155
|
let mut index = 0;
|
|
161
156
|
|
package/src/merkle_tree/mod.rs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
use super::file_utils;
|
|
2
2
|
use sha2::Digest;
|
|
3
|
-
use std::collections::BTreeMap;
|
|
4
3
|
use std::path::PathBuf;
|
|
5
|
-
use std::{fs, path::Path, sync::Arc};
|
|
4
|
+
use std::{collections::HashMap, fs, path::Path, sync::Arc};
|
|
6
5
|
use tokio::sync::RwLock;
|
|
7
6
|
use tonic::async_trait;
|
|
8
7
|
pub mod local_construction;
|
|
@@ -13,8 +12,7 @@ pub type MerkleNodePtr = Arc<RwLock<MerkleNode>>;
|
|
|
13
12
|
pub struct MerkleTree {
|
|
14
13
|
root_path: String,
|
|
15
14
|
root: MerkleNodePtr,
|
|
16
|
-
files:
|
|
17
|
-
cursor: Option<MerkleNodePtr>,
|
|
15
|
+
files: HashMap<String, File>,
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
#[derive(Debug)]
|
|
@@ -52,19 +50,12 @@ fn get_id() -> i32 {
|
|
|
52
50
|
|
|
53
51
|
#[async_trait]
|
|
54
52
|
pub trait LocalConstruction {
|
|
55
|
-
async fn new(
|
|
56
|
-
|
|
57
|
-
) -> Result<MerkleTree, anyhow::Error>;
|
|
58
|
-
|
|
59
|
-
async fn construct_merkle_tree(
|
|
60
|
-
root_directory: String,
|
|
61
|
-
) -> Result<MerkleTree, anyhow::Error>;
|
|
62
|
-
|
|
53
|
+
async fn new(root_directory: Option<String>) -> Result<MerkleTree, anyhow::Error>;
|
|
54
|
+
async fn construct_merkle_tree(root_directory: String) -> Result<MerkleTree, anyhow::Error>;
|
|
63
55
|
async fn update_file(
|
|
64
56
|
&mut self,
|
|
65
57
|
file_path: String,
|
|
66
58
|
) -> Result<(), anyhow::Error>;
|
|
67
|
-
|
|
68
59
|
async fn delete_file(
|
|
69
60
|
&mut self,
|
|
70
61
|
file_path: String,
|
|
@@ -88,257 +79,96 @@ impl MerkleTree {
|
|
|
88
79
|
pub fn empty_tree() -> MerkleTree {
|
|
89
80
|
MerkleTree {
|
|
90
81
|
root: Arc::new(RwLock::new(MerkleNode::empty_node(None, None))),
|
|
91
|
-
files:
|
|
82
|
+
files: HashMap::new(),
|
|
92
83
|
root_path: "".to_string(),
|
|
93
|
-
cursor: None,
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
pub async fn get_subtree_hash(
|
|
98
|
-
&self,
|
|
99
|
-
absolute_path: PathBuf,
|
|
100
|
-
) -> Result<String, anyhow::Error> {
|
|
101
|
-
let abs_string = match absolute_path.to_str() {
|
|
102
|
-
Some(s) => s.to_string(),
|
|
103
|
-
None => {
|
|
104
|
-
return Err(anyhow::anyhow!(
|
|
105
|
-
"get_subtree_hash: Failed to convert path to string"
|
|
106
|
-
))
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
let node = match self.files.get(&abs_string) {
|
|
111
|
-
Some(file) => file.node.clone(),
|
|
112
|
-
None => {
|
|
113
|
-
return Err(anyhow::anyhow!("Could not find file in tree!"));
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
let node_reader = node.read().await;
|
|
118
|
-
let node_hash = node_reader.hash.clone();
|
|
119
|
-
|
|
120
|
-
Ok(node_hash)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
pub async fn get_num_embeddable_files(&self) -> Result<i32, anyhow::Error> {
|
|
124
|
-
let mut count = 0;
|
|
125
|
-
|
|
126
|
-
for (_, file) in &self.files {
|
|
127
|
-
let file_reader = file.node.read().await;
|
|
128
|
-
match &file_reader.node_type {
|
|
129
|
-
NodeType::File(_) => {
|
|
130
|
-
count += 1;
|
|
131
|
-
}
|
|
132
|
-
NodeType::Branch(_) => {
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
NodeType::ErrorNode(_) => {
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
Ok(count)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
pub async fn get_num_embeddable_files_in_subtree(
|
|
145
|
-
&self,
|
|
146
|
-
absolute_path: PathBuf,
|
|
147
|
-
) -> Result<i32, anyhow::Error> {
|
|
148
|
-
let mut count = 0;
|
|
149
|
-
|
|
150
|
-
let absolute_path = match absolute_path.to_str() {
|
|
151
|
-
Some(s) => s.to_string(),
|
|
152
|
-
None => {
|
|
153
|
-
return Err(anyhow::anyhow!(
|
|
154
|
-
"get_num_embeddable_files_in_subtree: Failed to convert path to string"
|
|
155
|
-
))
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
// TODO(sualeh): worth keeping this list sorted.
|
|
160
|
-
|
|
161
|
-
for (_, file) in &self.files {
|
|
162
|
-
let file_reader = file.node.read().await;
|
|
163
|
-
match &file_reader.node_type {
|
|
164
|
-
NodeType::File(file_name) => {
|
|
165
|
-
if file_name.contains(&absolute_path) {
|
|
166
|
-
count += 1;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
NodeType::Branch(_) => {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
NodeType::ErrorNode(_) => {
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
Ok(count)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
pub async fn get_all_files(&self) -> Result<Vec<String>, anyhow::Error> {
|
|
182
|
-
let mut files = Vec::new();
|
|
183
|
-
|
|
184
|
-
for (file_name, file) in &self.files {
|
|
185
|
-
let file_reader = file.node.read().await;
|
|
186
|
-
match &file_reader.node_type {
|
|
187
|
-
NodeType::File(_) => {
|
|
188
|
-
files.push(file_name.clone());
|
|
189
|
-
}
|
|
190
|
-
NodeType::Branch(_) => {
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
NodeType::ErrorNode(_) => {
|
|
194
|
-
continue;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
Ok(files)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
pub async fn get_hashes_for_files(
|
|
203
|
-
&self,
|
|
204
|
-
files: Vec<String>,
|
|
205
|
-
) -> Result<Vec<String>, anyhow::Error> {
|
|
206
|
-
let mut hashes = Vec::new();
|
|
207
|
-
|
|
208
|
-
for file_name in files {
|
|
209
|
-
let file = match self.files.get(&file_name) {
|
|
210
|
-
Some(file) => file,
|
|
211
|
-
None => {
|
|
212
|
-
return Err(anyhow::anyhow!("Could not find file in tree!"));
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
let file_reader = file.node.read().await;
|
|
217
|
-
match &file_reader.node_type {
|
|
218
|
-
NodeType::File(_) => {
|
|
219
|
-
hashes.push(file_reader.hash.clone());
|
|
220
|
-
}
|
|
221
|
-
NodeType::Branch(_) => {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
NodeType::ErrorNode(_) => {
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
84
|
}
|
|
229
|
-
|
|
230
|
-
Ok(hashes)
|
|
231
85
|
}
|
|
232
86
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
87
|
+
pub async fn get_subtree_hash(&self, path: String) -> Result<String, anyhow::Error> {
|
|
88
|
+
let path = PathBuf::from(path);
|
|
89
|
+
let node = match self.files.get(path.to_str().unwrap()) {
|
|
90
|
+
Some(file) => file.node.clone(),
|
|
91
|
+
None => {
|
|
92
|
+
return Err(anyhow::anyhow!("Could not find file in tree!"));
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
let node_reader = node.read().await;
|
|
97
|
+
let node_hash = node_reader.hash.clone();
|
|
98
|
+
|
|
99
|
+
Ok(node_hash)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
pub async fn get_num_embeddable_files(&self) -> Result<i32, anyhow::Error> {
|
|
103
|
+
let mut count = 0;
|
|
104
|
+
|
|
105
|
+
for (_, file) in &self.files {
|
|
106
|
+
let file_reader = file.node.read().await;
|
|
107
|
+
match &file_reader.node_type {
|
|
108
|
+
NodeType::File(_) => {
|
|
109
|
+
count += 1;
|
|
110
|
+
}
|
|
111
|
+
NodeType::Branch(_) => {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
NodeType::ErrorNode(_) => {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Ok(count)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
pub async fn get_all_files(&self) -> Result<Vec<String>, anyhow::Error> {
|
|
124
|
+
let mut files = Vec::new();
|
|
125
|
+
|
|
126
|
+
for (file_name, file) in &self.files {
|
|
127
|
+
let file_reader = file.node.read().await;
|
|
128
|
+
match &file_reader.node_type {
|
|
129
|
+
NodeType::File(_) => {
|
|
130
|
+
files.push(file_name.clone());
|
|
131
|
+
}
|
|
132
|
+
NodeType::Branch(_) => {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
NodeType::ErrorNode(_) => {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
Ok(files)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
pub async fn get_hashes_for_files(&self, files: Vec<String>) -> Result<Vec<String>, anyhow::Error> {
|
|
145
|
+
let mut hashes = Vec::new();
|
|
146
|
+
|
|
147
|
+
for file_name in files {
|
|
148
|
+
let file = match self.files.get(&file_name) {
|
|
149
|
+
Some(file) => file,
|
|
150
|
+
None => {
|
|
151
|
+
return Err(anyhow::anyhow!("Could not find file in tree!"));
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
let file_reader = file.node.read().await;
|
|
156
|
+
match &file_reader.node_type {
|
|
157
|
+
NodeType::File(_) => {
|
|
158
|
+
hashes.push(file_reader.hash.clone());
|
|
159
|
+
}
|
|
160
|
+
NodeType::Branch(_) => {
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
NodeType::ErrorNode(_) => {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
Ok(hashes)
|
|
170
|
+
}
|
|
307
171
|
|
|
308
|
-
// everytime we get to a child list, we will add all the children to a fifo, and then pull from it as long as we need it.
|
|
309
|
-
|
|
310
|
-
// algorithm:
|
|
311
|
-
// 1.
|
|
312
|
-
|
|
313
|
-
Err(anyhow::anyhow!("Could not find file to embed!"))
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
pub async fn get_all_dir_files_to_embed(
|
|
317
|
-
&self,
|
|
318
|
-
absolute_path: &str,
|
|
319
|
-
) -> Result<Vec<String>, anyhow::Error> {
|
|
320
|
-
let mut files = Vec::new();
|
|
321
|
-
|
|
322
|
-
for (file_path, f) in &self.files {
|
|
323
|
-
if !file_path.contains(absolute_path) {
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
match f.node.read().await.node_type {
|
|
328
|
-
NodeType::File(_) => {
|
|
329
|
-
files.push(file_path.clone());
|
|
330
|
-
}
|
|
331
|
-
NodeType::Branch(_) => {
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
NodeType::ErrorNode(_) => {
|
|
335
|
-
continue;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
Ok(files)
|
|
341
|
-
}
|
|
342
172
|
|
|
343
173
|
/// creates a new node and attaches it to the current tree.
|
|
344
174
|
/// SPEC:
|
|
@@ -404,7 +234,7 @@ impl MerkleTree {
|
|
|
404
234
|
}
|
|
405
235
|
};
|
|
406
236
|
|
|
407
|
-
|
|
237
|
+
Ok(new_node)
|
|
408
238
|
}
|
|
409
239
|
|
|
410
240
|
/// Spec:
|
|
@@ -468,21 +298,17 @@ impl MerkleTree {
|
|
|
468
298
|
/// - attaches to the ancestor.
|
|
469
299
|
/// - adds to the filemap
|
|
470
300
|
/// - updates hashes of ancestor path.
|
|
471
|
-
async fn attach_new_node_to_tree(
|
|
472
|
-
&mut self,
|
|
473
|
-
file_path: String,
|
|
474
|
-
) -> Result<(), anyhow::Error> {
|
|
301
|
+
async fn attach_new_node_to_tree(&mut self, file_path: String) -> Result<(), anyhow::Error> {
|
|
475
302
|
let path = PathBuf::from(file_path.clone());
|
|
476
303
|
match self.create_new_node_and_attach_to_ancestors(path).await {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
304
|
+
Ok(node_ptr) => {
|
|
305
|
+
self.add_subtree_to_filemap(node_ptr).await;
|
|
306
|
+
Ok(())
|
|
307
|
+
}
|
|
308
|
+
Err(e) => {
|
|
309
|
+
Err(anyhow::anyhow!("Could not create new node and attach to ancestors! {}", e.to_string()))
|
|
310
|
+
}
|
|
311
|
+
}
|
|
486
312
|
}
|
|
487
313
|
|
|
488
314
|
/// MUTATES MUTATES MUTATES
|
|
@@ -563,22 +389,20 @@ impl MerkleTree {
|
|
|
563
389
|
.create_new_node_and_attach_to_ancestors(file_path)
|
|
564
390
|
.await;
|
|
565
391
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
}
|
|
392
|
+
match node_ptr {
|
|
393
|
+
Ok(node_ptr) => {
|
|
394
|
+
|
|
395
|
+
self.files.insert(
|
|
396
|
+
file_string,
|
|
397
|
+
File {
|
|
398
|
+
node: node_ptr.clone(),
|
|
399
|
+
},
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
Err(e) => {
|
|
403
|
+
return Err(anyhow::anyhow!("Could not create new node and attach to ancestors! {}", e.to_string()));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
582
406
|
|
|
583
407
|
Ok(())
|
|
584
408
|
}
|
|
@@ -708,15 +532,15 @@ impl MerkleNode {
|
|
|
708
532
|
));
|
|
709
533
|
}
|
|
710
534
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
535
|
+
// check if the directory fails the bad dir test.
|
|
536
|
+
let is_bad_dir = file_utils::is_in_bad_dir(file_or_directory);
|
|
537
|
+
if is_bad_dir.is_err() || is_bad_dir.unwrap_or(false) {
|
|
538
|
+
// println!("skipping directory: {}", path_str);
|
|
539
|
+
return Arc::new(RwLock::new(MerkleNode::empty_node(
|
|
540
|
+
Some(file_or_directory),
|
|
541
|
+
Some("Directory is in bad dir!".to_string()),
|
|
542
|
+
)));
|
|
543
|
+
}
|
|
720
544
|
|
|
721
545
|
let entries = fs::read_dir(file_or_directory);
|
|
722
546
|
match entries {
|
|
@@ -831,7 +655,7 @@ impl MerkleNode {
|
|
|
831
655
|
Ok(node) => node,
|
|
832
656
|
Err(e) => {
|
|
833
657
|
// println!("constructing error node. error: {}", e);
|
|
834
|
-
|
|
658
|
+
// println!("file_path: {:?}", file_path);
|
|
835
659
|
MerkleNode::empty_node(Some(file_path), Some(e))
|
|
836
660
|
}
|
|
837
661
|
};
|