diff --git a/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so b/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so index 858ccbb..9906dd3 100755 Binary files a/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so and b/android/library-encrypt/src/main/jniLibs/arm64-v8a/libmmkv.so differ diff --git a/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so b/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so index 8a8e75b..ebbc9b3 100755 Binary files a/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so and b/android/library-encrypt/src/main/jniLibs/armeabi-v7a/libmmkv.so differ diff --git a/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so b/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so index 37cb842..1df5b2e 100755 Binary files a/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so and b/android/library-encrypt/src/main/jniLibs/x86_64/libmmkv.so differ diff --git a/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so b/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so index fe6ed9b..2ac8648 100755 Binary files a/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so and b/android/library/src/main/jniLibs/arm64-v8a/libmmkv.so differ diff --git a/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so b/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so index 6b4343f..d26ca14 100755 Binary files a/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so and b/android/library/src/main/jniLibs/armeabi-v7a/libmmkv.so differ diff --git a/android/library/src/main/jniLibs/x86_64/libmmkv.so b/android/library/src/main/jniLibs/x86_64/libmmkv.so index c6d400e..faa9992 100755 Binary files a/android/library/src/main/jniLibs/x86_64/libmmkv.so and b/android/library/src/main/jniLibs/x86_64/libmmkv.so differ diff --git a/ios/MMKV/RustMMKV.xcframework.zip b/ios/MMKV/RustMMKV.xcframework.zip index a4421ed..cc1356b 100644 Binary files a/ios/MMKV/RustMMKV.xcframework.zip and b/ios/MMKV/RustMMKV.xcframework.zip differ diff --git a/src/core/iter.rs b/src/core/iter.rs index 2e71736..328fe98 100644 --- a/src/core/iter.rs +++ b/src/core/iter.rs @@ -19,7 +19,7 @@ impl MemoryMap { F: Fn(&[u8]) -> crate::Result, { let start = LEN_OFFSET; - let end = self.len(); + let end = self.content_len(); Iter { mm: self, start, diff --git a/src/core/memory_map.rs b/src/core/memory_map.rs index 5c7c231..dc99270 100644 --- a/src/core/memory_map.rs +++ b/src/core/memory_map.rs @@ -75,7 +75,6 @@ impl DerefMut for RawMmap { } unsafe impl Send for RawMmap {} -unsafe impl Sync for RawMmap {} #[derive(Debug)] pub struct MemoryMap(RawMmap); @@ -88,7 +87,7 @@ impl MemoryMap { pub fn append(&mut self, value: Vec) -> io::Result<()> { let data_len = value.len(); - let start = self.len(); + let start = self.content_len(); let content_len = start - LEN_OFFSET; let end = data_len + start; let new_content_len = data_len + content_len; @@ -103,10 +102,16 @@ impl MemoryMap { self.0.flush(LEN_OFFSET) } - pub fn len(&self) -> usize { + /// The content len of current mmap + pub fn content_len(&self) -> usize { usize::from_be_bytes(self.0[0..LEN_OFFSET].try_into().unwrap()) + LEN_OFFSET } + /// The max len of current mmap + pub fn len(&self) -> usize { + self.0.len + } + pub fn read(&self, range: Range) -> &[u8] { self.0[range].as_ref() } @@ -130,21 +135,21 @@ mod tests { .unwrap(); file.set_len(1024).unwrap(); let mut mm = MemoryMap::new(&file, 1024); - assert_eq!(mm.len(), 8); + assert_eq!(mm.content_len(), 8); mm.append(vec![1, 2, 3]).unwrap(); mm.append(vec![4]).unwrap(); - assert_eq!(mm.len(), 12); + assert_eq!(mm.content_len(), 12); let read = mm.read(8..10); assert_eq!(read.len(), 2); assert_eq!(read[0], 1); assert_eq!(read[1], 2); - let read = mm.read(mm.len() - 1..mm.len()); + let read = mm.read(mm.content_len() - 1..mm.content_len()); assert_eq!(read[0], 4); mm.reset().unwrap(); mm.append(vec![5, 4, 3, 2, 1]).unwrap(); - assert_eq!(mm.len(), 13); + assert_eq!(mm.content_len(), 13); let read = mm.read(8..9); assert_eq!(read[0], 5); diff --git a/src/core/mmkv_impl.rs b/src/core/mmkv_impl.rs index 91d7fba..2d9361d 100644 --- a/src/core/mmkv_impl.rs +++ b/src/core/mmkv_impl.rs @@ -60,14 +60,14 @@ impl IOWriter { } // Flash the data to file, always running in one io thread, so don't need lock here - fn write(&mut self, buffer: Buffer, map: HashMap, duplicated: bool) { + fn write(&mut self, buffer: Buffer, duplicated: bool, snapshot: HashMap) { let data = self.encoder.encode_to_bytes(&buffer).unwrap(); - let target_end = data.len() + self.mm.len(); - let file_size = self.config.file_size(); + let target_end = data.len() + self.mm.content_len(); + let max_len = self.mm.len(); if duplicated { self.need_trim = true; } - if target_end as u64 <= file_size { + if target_end <= max_len { self.mm.append(data).unwrap(); return; } @@ -76,15 +76,15 @@ impl IOWriter { #[cfg(feature = "encryption")] self.encryptor.reset(); let time_start = Instant::now(); - info!(LOG_TAG, "start trim, current len {}", self.mm.len()); + info!(LOG_TAG, "start trim, current len {}", self.mm.content_len()); let mut count = 0; self.mm .reset() .map_err(|e| EncodeFailed(e.to_string())) .unwrap(); - for buffer in map.values() { + for buffer in snapshot.values() { let bytes = self.encoder.encode_to_bytes(buffer).unwrap(); - if self.mm.len() + bytes.len() > file_size as usize { + if self.mm.content_len() + bytes.len() > max_len { self.expand(); } self.mm.append(bytes).unwrap(); @@ -95,7 +95,7 @@ impl IOWriter { LOG_TAG, "wrote {} items, new len {}, cost {:?}", count, - self.mm.len(), + self.mm.content_len(), time_start.elapsed() ); } else { @@ -145,7 +145,8 @@ impl MmkvImpl { #[cfg(feature = "encryption")] encryptor, ); - let content_len = io_writer.mm.len(); + let content_len = io_writer.mm.content_len(); + let file_len = io_writer.mm.len(); let mmkv = MmkvImpl { kv_map, is_valid: true, @@ -153,9 +154,10 @@ impl MmkvImpl { }; info!( LOG_TAG, - "instance initialized, read {} items, content len {}, cost {:?}", + "instance initialized, read {} items, content len {}, file len {}, cost {:?}", mmkv.kv_map.len(), content_len, + file_len, time_start.elapsed() ); mmkv @@ -167,12 +169,12 @@ impl MmkvImpl { } let result = self.kv_map.insert(key.to_string(), raw_buffer.clone()); let duplicated = result.is_some(); - let map = self.kv_map.clone(); + let snapshot = self.kv_map.clone(); self.io_looper.as_ref().unwrap().post(move |callback| { callback .downcast_mut::() .unwrap() - .write(raw_buffer, map, duplicated) + .write(raw_buffer, duplicated, snapshot) }) } @@ -242,7 +244,10 @@ mod tests { .as_ref() .unwrap() .post(|writer| { - assert_eq!(writer.downcast_ref::().unwrap().mm.len(), $value); + assert_eq!( + writer.downcast_ref::().unwrap().mm.content_len(), + $value + ); }) .expect(""); }; diff --git a/src/mmkv.rs b/src/mmkv.rs index 903c399..0c01735 100644 --- a/src/mmkv.rs +++ b/src/mmkv.rs @@ -62,7 +62,8 @@ impl MMKV { Initialize the MMKV instance with a writeable directory, absolute or relative paths are acceptable. - All API calls before initialization will panic. + All API calls(except [set_logger](MMKV::set_logger), [set_log_level](MMKV::set_log_level)) + before initialization will panic. Calling [initialize](MMKV::initialize) multiple times is allowed, the old instance will be closed (see [close](MMKV::close)), the last call will take over.