@@ -97,13 +97,122 @@ impl crate::application::CoLink {
9797 Ok ( chunk_paths_string)
9898 }
9999
100+ async fn _store_chunks_compatibility_mode (
101+ & self ,
102+ payload : & [ u8 ] ,
103+ key_name : & str ,
104+ ) -> Result < i32 , Error > {
105+ let mut offset = 0 ;
106+ let mut chunk_id = 0 ;
107+ while offset < payload. len ( ) {
108+ let chunk_size = if offset + CHUNK_SIZE > payload. len ( ) {
109+ payload. len ( ) - offset
110+ } else {
111+ CHUNK_SIZE
112+ } ;
113+ self . update_entry (
114+ & format ! ( "{}:{}" , key_name, chunk_id) ,
115+ & payload[ offset..offset + chunk_size] ,
116+ )
117+ . await ?;
118+ offset += chunk_size;
119+ chunk_id += 1 ;
120+ }
121+ Ok ( chunk_id)
122+ }
123+
124+ async fn _append_chunks_compatibility_mode (
125+ & self ,
126+ chunk_len : i32 ,
127+ payload : & [ u8 ] ,
128+ key_name : & str ,
129+ ) -> Result < i32 , Error > {
130+ let last_chunk_id = chunk_len - 1 ;
131+ let mut last_chunk = self
132+ . read_entry ( & format ! ( "{}:{}" , key_name, last_chunk_id, ) )
133+ . await ?;
134+ let mut offset = 0 ;
135+ let mut chunk_id = chunk_len;
136+ if last_chunk. len ( ) < CHUNK_SIZE {
137+ let chunk_size = if payload. len ( ) < CHUNK_SIZE - last_chunk. len ( ) {
138+ payload. len ( )
139+ } else {
140+ CHUNK_SIZE - last_chunk. len ( )
141+ } ;
142+ last_chunk. append ( & mut payload[ ..chunk_size] . to_vec ( ) ) ;
143+ self . update_entry ( & format ! ( "{}:{}" , key_name, last_chunk_id) , & last_chunk)
144+ . await ?;
145+ offset = chunk_size;
146+ }
147+ while offset < payload. len ( ) {
148+ let chunk_size = if offset + CHUNK_SIZE > payload. len ( ) {
149+ payload. len ( ) - offset
150+ } else {
151+ CHUNK_SIZE
152+ } ;
153+ self . update_entry (
154+ & format ! ( "{}:{}" , key_name, chunk_id) ,
155+ & payload[ offset..offset + chunk_size] ,
156+ )
157+ . await ?;
158+ offset += chunk_size;
159+ chunk_id += 1 ;
160+ }
161+ Ok ( chunk_id)
162+ }
163+
164+ async fn _delete_chunks_compatibility_mode ( & self , key_name : & str ) -> Result < String , Error > {
165+ let metadata_key = format ! ( "{}:chunk_metadata" , key_name) ;
166+ let chunk_len = self . read_entry ( & metadata_key) . await ?;
167+ let chunk_len = String :: from_utf8_lossy ( & chunk_len) . parse :: < i32 > ( ) ?;
168+ let res = self . delete_entry ( & metadata_key) . await ?;
169+ for i in 0 ..chunk_len {
170+ self . delete_entry ( & format ! ( "{}:{}" , key_name, i) ) . await ?;
171+ }
172+ Ok ( res)
173+ }
174+
175+ async fn _chunk_lock_compatibility_mode ( & self , key_name : & str ) -> Result < ( ) , Error > {
176+ loop {
177+ if self
178+ . create_entry ( & format ! ( "{}:chunk_lock" , key_name) , b"" )
179+ . await
180+ . is_ok ( )
181+ {
182+ return Ok ( ( ) ) ;
183+ }
184+ tokio:: time:: sleep ( tokio:: time:: Duration :: from_millis ( 100 ) ) . await ;
185+ }
186+ }
187+
188+ async fn _chunk_unlock_compatibility_mode ( & self , key_name : & str ) -> Result < ( ) , Error > {
189+ self . delete_entry ( & format ! ( "{}:chunk_lock" , key_name) )
190+ . await ?;
191+ Ok ( ( ) )
192+ }
193+
100194 #[ async_recursion]
101195 pub ( crate ) async fn _create_entry_chunk (
102196 & self ,
103197 key_name : & str ,
104198 payload : & [ u8 ] ,
105199 ) -> Result < String , Error > {
106200 let metadata_key = format ! ( "{}:chunk_metadata" , key_name) ;
201+ if key_name. contains ( '$' ) {
202+ self . _chunk_lock_compatibility_mode ( key_name) . await ?;
203+ if let Err ( e) = self . create_entry ( & metadata_key, b"0" ) . await {
204+ self . _chunk_unlock_compatibility_mode ( key_name) . await ?;
205+ return Err ( e) ;
206+ }
207+ let chunk_len = self
208+ . _store_chunks_compatibility_mode ( payload, key_name)
209+ . await ?;
210+ let res = self
211+ . update_entry ( & metadata_key, chunk_len. to_string ( ) . as_bytes ( ) )
212+ . await ?;
213+ self . _chunk_unlock_compatibility_mode ( key_name) . await ?;
214+ return Ok ( res) ;
215+ }
107216 // lock the metadata entry to prevent simultaneous writes
108217 let lock_token = self . lock ( & metadata_key) . await ?;
109218 // use a closure to prevent locking forever caused by errors
@@ -114,7 +223,7 @@ impl crate::application::CoLink {
114223 let chunk_paths_string = self . _check_chunk_paths_size ( chunk_paths) ?;
115224 // store the chunk paths in the metadata entry and update metadata
116225 let response = self
117- . create_entry ( & metadata_key, & chunk_paths_string. into_bytes ( ) )
226+ . create_entry ( & metadata_key, chunk_paths_string. as_bytes ( ) )
118227 . await ?;
119228 Ok :: < String , Error > ( response)
120229 }
@@ -126,6 +235,22 @@ impl crate::application::CoLink {
126235 #[ async_recursion]
127236 pub ( crate ) async fn _read_entry_chunk ( & self , key_name : & str ) -> Result < Vec < u8 > , Error > {
128237 let metadata_key = format ! ( "{}:chunk_metadata" , key_name) ;
238+ if key_name. contains ( '$' ) {
239+ self . _chunk_lock_compatibility_mode ( key_name) . await ?;
240+ let res = async {
241+ let chunk_len = self . read_entry ( & metadata_key) . await ?;
242+ let chunk_len = String :: from_utf8_lossy ( & chunk_len) . parse :: < i32 > ( ) ?;
243+ let mut payload = Vec :: new ( ) ;
244+ for i in 0 ..chunk_len {
245+ let mut res = self . read_entry ( & format ! ( "{}:{}" , key_name, i) ) . await ?;
246+ payload. append ( & mut res) ;
247+ }
248+ Ok :: < Vec < u8 > , Error > ( payload)
249+ }
250+ . await ;
251+ self . _chunk_unlock_compatibility_mode ( key_name) . await ?;
252+ return res;
253+ }
129254 let metadata_response = self . read_entry ( & metadata_key) . await ?;
130255 let payload_string = String :: from_utf8 ( metadata_response) ?;
131256 let user_id = self . get_user_id ( ) ?;
@@ -149,6 +274,18 @@ impl crate::application::CoLink {
149274 payload : & [ u8 ] ,
150275 ) -> Result < String , Error > {
151276 let metadata_key = format ! ( "{}:chunk_metadata" , key_name) ;
277+ if key_name. contains ( '$' ) {
278+ self . _chunk_lock_compatibility_mode ( key_name) . await ?;
279+ let _ = self . _delete_chunks_compatibility_mode ( key_name) . await ;
280+ let chunk_len = self
281+ . _store_chunks_compatibility_mode ( payload, key_name)
282+ . await ?;
283+ let res = self
284+ . update_entry ( & metadata_key, chunk_len. to_string ( ) . as_bytes ( ) )
285+ . await ?;
286+ self . _chunk_unlock_compatibility_mode ( key_name) . await ?;
287+ return Ok ( res) ;
288+ }
152289 // lock the metadata entry to prevent simultaneous writes
153290 let lock_token = self . lock ( & metadata_key) . await ?;
154291 // use a closure to prevent locking forever caused by errors
@@ -159,7 +296,7 @@ impl crate::application::CoLink {
159296 let chunk_paths_string = self . _check_chunk_paths_size ( chunk_paths) ?;
160297 // update the metadata entry
161298 let response = self
162- . update_entry ( & metadata_key, & chunk_paths_string. into_bytes ( ) )
299+ . update_entry ( & metadata_key, chunk_paths_string. as_bytes ( ) )
163300 . await ?;
164301 Ok :: < String , Error > ( response)
165302 }
@@ -175,6 +312,19 @@ impl crate::application::CoLink {
175312 payload : & [ u8 ] ,
176313 ) -> Result < String , Error > {
177314 let metadata_key = format ! ( "{}:chunk_metadata" , key_name) ;
315+ if key_name. contains ( '$' ) {
316+ self . _chunk_lock_compatibility_mode ( key_name) . await ?;
317+ let chunk_len = self . read_entry ( & metadata_key) . await ?;
318+ let chunk_len = String :: from_utf8_lossy ( & chunk_len) . parse :: < i32 > ( ) ?;
319+ let new_chunk_len = self
320+ . _append_chunks_compatibility_mode ( chunk_len, payload, key_name)
321+ . await ?;
322+ let res = self
323+ . update_entry ( & metadata_key, new_chunk_len. to_string ( ) . as_bytes ( ) )
324+ . await ?;
325+ self . _chunk_unlock_compatibility_mode ( key_name) . await ?;
326+ return Ok ( res) ;
327+ }
178328 // lock the metadata entry to prevent simultaneous writes
179329 let lock_token = self . lock ( & metadata_key) . await ?;
180330 // use a closure to prevent locking forever caused by errors
@@ -189,7 +339,7 @@ impl crate::application::CoLink {
189339 let chunk_paths_string = self . _check_chunk_paths_size ( chunk_paths) ?;
190340 // update the metadata entry
191341 let response = self
192- . update_entry ( & metadata_key, & chunk_paths_string. into_bytes ( ) )
342+ . update_entry ( & metadata_key, chunk_paths_string. as_bytes ( ) )
193343 . await ?;
194344 Ok :: < String , Error > ( response)
195345 }
@@ -200,6 +350,12 @@ impl crate::application::CoLink {
200350
201351 #[ async_recursion]
202352 pub ( crate ) async fn _delete_entry_chunk ( & self , key_name : & str ) -> Result < String , Error > {
353+ if key_name. contains ( '$' ) {
354+ self . _chunk_lock_compatibility_mode ( key_name) . await ?;
355+ let res = self . _delete_chunks_compatibility_mode ( key_name) . await ;
356+ self . _chunk_unlock_compatibility_mode ( key_name) . await ?;
357+ return res;
358+ }
203359 let metadata_key = format ! ( "{}:chunk_metadata" , key_name) ;
204360 let lock_token = self . lock ( & metadata_key) . await ?;
205361 let res = self . delete_entry ( & metadata_key) . await ;
0 commit comments