react-native-mmkv 2.11.0 → 2.12.0
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/MMKV/Core/CodedInputData.cpp +28 -4
- package/MMKV/Core/CodedInputData.h +5 -1
- package/MMKV/Core/CodedOutputData.cpp +12 -0
- package/MMKV/Core/CodedOutputData.h +6 -0
- package/MMKV/Core/MMBuffer.cpp +7 -0
- package/MMKV/Core/MMBuffer.h +3 -0
- package/MMKV/Core/MMKV.cpp +114 -19
- package/MMKV/Core/MMKV.h +69 -33
- package/MMKV/Core/MMKVPredef.h +1 -1
- package/MMKV/Core/MMKV_Android.cpp +10 -8
- package/MMKV/Core/MMKV_IO.cpp +386 -60
- package/MMKV/Core/MMKV_OSX.cpp +51 -30
- package/MMKV/Core/MMKV_OSX.h +10 -4
- package/MMKV/Core/MemoryFile.cpp +31 -11
- package/MMKV/Core/MemoryFile.h +8 -3
- package/MMKV/Core/MemoryFile_Android.cpp +2 -2
- package/MMKV/Core/MemoryFile_OSX.cpp +2 -3
- package/MMKV/Core/MemoryFile_Win32.cpp +8 -5
- package/MMKV/Core/MiniPBCoder.cpp +11 -0
- package/MMKV/Core/MiniPBCoder.h +3 -0
- package/MMKV/Core/MiniPBCoder_OSX.cpp +8 -0
- package/MMKV/Core/ThreadLock.cpp +5 -0
- package/MMKV/Core/ThreadLock.h +4 -0
- package/MMKV/Core/aes/openssl/openssl_aes-armv4.S +8 -0
- package/MMKV/Core/core.vcxproj +3 -3
- package/MMKV/README.md +3 -3
- package/android/build.gradle +16 -3
- package/android/src/hasNamespace/AndroidManifest.xml +3 -0
- package/android/src/main/cpp/cpp-adapter.cpp +7 -1
- package/ios/MmkvModule.mm +8 -2
- package/lib/commonjs/createMMKV.web.js +1 -1
- package/lib/commonjs/createMMKV.web.js.map +1 -1
- package/lib/commonjs/hooks.js +15 -10
- package/lib/commonjs/hooks.js.map +1 -1
- package/lib/module/createMMKV.web.js +1 -1
- package/lib/module/createMMKV.web.js.map +1 -1
- package/lib/module/hooks.js +15 -10
- package/lib/module/hooks.js.map +1 -1
- package/lib/typescript/createMMKV.web.d.ts.map +1 -1
- package/lib/typescript/hooks.d.ts.map +1 -1
- package/package.json +1 -1
- package/react-native-mmkv.podspec +1 -1
- package/src/createMMKV.web.ts +4 -2
- package/src/hooks.ts +18 -13
- package/MMKV/LICENSE.TXT +0 -193
package/MMKV/Core/MMKV_OSX.cpp
CHANGED
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
# include "ThreadLock.h"
|
|
34
34
|
# include "aes/AESCrypt.h"
|
|
35
35
|
# include <sys/utsname.h>
|
|
36
|
+
# include <sys/sysctl.h>
|
|
37
|
+
# include "MMKV_OSX.h"
|
|
36
38
|
|
|
37
39
|
# ifdef MMKV_IOS
|
|
38
|
-
# include "MMKV_OSX.h"
|
|
39
40
|
# include <sys/mman.h>
|
|
40
41
|
# endif
|
|
41
42
|
|
|
@@ -53,9 +54,6 @@ using namespace mmkv;
|
|
|
53
54
|
extern ThreadLock *g_instanceLock;
|
|
54
55
|
extern MMKVPath_t g_rootDir;
|
|
55
56
|
|
|
56
|
-
enum { UnKnown = 0, PowerMac = 1, Mac, iPhone, iPod, iPad, AppleTV, AppleWatch };
|
|
57
|
-
static void GetAppleMachineInfo(int &device, int &version);
|
|
58
|
-
|
|
59
57
|
MMKV_NAMESPACE_BEGIN
|
|
60
58
|
|
|
61
59
|
# ifdef MMKV_IOS
|
|
@@ -86,24 +84,9 @@ MLockPtr::~MLockPtr() {
|
|
|
86
84
|
}
|
|
87
85
|
}
|
|
88
86
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
extern ThreadOnceToken_t once_control;
|
|
92
|
-
extern void initialize();
|
|
87
|
+
bool MLockPtr::isMLockPtrEnabled = true;
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
ThreadLock::ThreadOnce(&once_control, initialize);
|
|
96
|
-
|
|
97
|
-
// crc32 instruction requires A10 chip, aka iPhone 7 or iPad 6th generation
|
|
98
|
-
int device = 0, version = 0;
|
|
99
|
-
GetAppleMachineInfo(device, version);
|
|
100
|
-
MMKVInfo("Apple Device:%d, version:%d", device, version);
|
|
101
|
-
|
|
102
|
-
g_rootDir = defaultRootDir;
|
|
103
|
-
mkPath(g_rootDir);
|
|
104
|
-
|
|
105
|
-
MMKVInfo("default root dir: " MMKV_PATH_FORMAT, g_rootDir.c_str());
|
|
106
|
-
}
|
|
89
|
+
# endif
|
|
107
90
|
|
|
108
91
|
# ifdef MMKV_IOS
|
|
109
92
|
|
|
@@ -123,7 +106,7 @@ bool MMKV::isInBackground() {
|
|
|
123
106
|
}
|
|
124
107
|
|
|
125
108
|
pair<bool, MLockPtr> guardForBackgroundWriting(void *ptr, size_t size) {
|
|
126
|
-
if (g_isInBackground) {
|
|
109
|
+
if (g_isInBackground && MLockPtr::isMLockPtrEnabled) {
|
|
127
110
|
MLockPtr mlockPtr(ptr, size);
|
|
128
111
|
return make_pair(mlockPtr.isLocked(), std::move(mlockPtr));
|
|
129
112
|
} else {
|
|
@@ -189,9 +172,9 @@ bool MMKV::set(NSObject<NSCoding> *__unsafe_unretained obj, MMKVKey_t key, uint3
|
|
|
189
172
|
} else {
|
|
190
173
|
MMBuffer data(archived, MMBufferNoCopy);
|
|
191
174
|
if (data.length() > 0) {
|
|
192
|
-
auto tmp = MMBuffer(
|
|
175
|
+
auto tmp = MMBuffer(data.length() + Fixed32Size);
|
|
193
176
|
CodedOutputData output(tmp.getPtr(), tmp.length());
|
|
194
|
-
output.
|
|
177
|
+
output.writeRawData(data); // NSKeyedArchiver has its own size management
|
|
195
178
|
auto time = (expireDuration != 0) ? getCurrentTimeInSecond() + expireDuration : 0;
|
|
196
179
|
output.writeRawLittleEndian32(UInt32ToInt32(time));
|
|
197
180
|
data = std::move(tmp);
|
|
@@ -240,6 +223,8 @@ NSObject *MMKV::getObject(MMKVKey_t key, Class cls) {
|
|
|
240
223
|
return result;
|
|
241
224
|
} catch (std::exception &exception) {
|
|
242
225
|
MMKVError("%s", exception.what());
|
|
226
|
+
} catch (...) {
|
|
227
|
+
MMKVError("decode fail");
|
|
243
228
|
}
|
|
244
229
|
} else {
|
|
245
230
|
if ([cls conformsToProtocol:@protocol(NSCoding)]) {
|
|
@@ -271,12 +256,50 @@ MMKV::appendDataWithKey(const MMBuffer &data, MMKVKey_t key, const KeyValueHolde
|
|
|
271
256
|
|
|
272
257
|
return doAppendDataWithKey(data, keyData, isDataHolder, keyLength);
|
|
273
258
|
}
|
|
259
|
+
|
|
260
|
+
pair<bool, KeyValueHolder>
|
|
261
|
+
MMKV::overrideDataWithKey(const MMBuffer &data, MMKVKey_t key, const KeyValueHolderCrypt &kvHolder, bool isDataHolder) {
|
|
262
|
+
size_t old_actualSize = m_actualSize;
|
|
263
|
+
size_t old_position = m_output->getPosition();
|
|
264
|
+
// only one key in dict, do not append, just rewrite from beginning
|
|
265
|
+
m_actualSize = 0;
|
|
266
|
+
m_output->setPosition(0);
|
|
267
|
+
|
|
268
|
+
auto m_tmpDic = m_dic;
|
|
269
|
+
auto m_tmpDicCrypt = m_dicCrypt;
|
|
270
|
+
if (m_crypter) {
|
|
271
|
+
m_dicCrypt = new MMKVMapCrypt();
|
|
272
|
+
} else {
|
|
273
|
+
m_dic = new MMKVMap();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
auto ret = appendDataWithKey(data, key, kvHolder, isDataHolder);
|
|
277
|
+
if (!ret.first) {
|
|
278
|
+
// rollback
|
|
279
|
+
m_actualSize = old_actualSize;
|
|
280
|
+
m_output->setPosition(old_position);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (m_crypter) {
|
|
284
|
+
delete m_dicCrypt;
|
|
285
|
+
m_dicCrypt = m_tmpDicCrypt;
|
|
286
|
+
} else {
|
|
287
|
+
delete m_dic;
|
|
288
|
+
m_dic = m_tmpDic;
|
|
289
|
+
}
|
|
290
|
+
return ret;
|
|
291
|
+
}
|
|
274
292
|
# endif
|
|
275
293
|
|
|
276
|
-
NSArray *MMKV::allKeys() {
|
|
294
|
+
NSArray *MMKV::allKeys(bool filterExpire) {
|
|
277
295
|
SCOPED_LOCK(m_lock);
|
|
278
296
|
checkLoadData();
|
|
279
297
|
|
|
298
|
+
if (unlikely(filterExpire && m_enableKeyExpire)) {
|
|
299
|
+
SCOPED_LOCK(m_exclusiveProcessLock);
|
|
300
|
+
fullWriteback(nullptr, true);
|
|
301
|
+
}
|
|
302
|
+
|
|
280
303
|
NSMutableArray *keys = [NSMutableArray array];
|
|
281
304
|
if (m_crypter) {
|
|
282
305
|
for (const auto &pair : *m_dicCrypt) {
|
|
@@ -359,11 +382,7 @@ void MMKV::enumerateKeys(EnumerateBlock block) {
|
|
|
359
382
|
MMKVInfo("enumerate [%s] finish", m_mmapID.c_str());
|
|
360
383
|
}
|
|
361
384
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
# include <sys/sysctl.h>
|
|
365
|
-
|
|
366
|
-
static void GetAppleMachineInfo(int &device, int &version) {
|
|
385
|
+
void GetAppleMachineInfo(int &device, int &version) {
|
|
367
386
|
device = UnKnown;
|
|
368
387
|
version = 0;
|
|
369
388
|
|
|
@@ -401,4 +420,6 @@ static void GetAppleMachineInfo(int &device, int &version) {
|
|
|
401
420
|
}
|
|
402
421
|
}
|
|
403
422
|
|
|
423
|
+
MMKV_NAMESPACE_END
|
|
424
|
+
|
|
404
425
|
#endif // MMKV_APPLE
|
package/MMKV/Core/MMKV_OSX.h
CHANGED
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
#pragma once
|
|
22
22
|
#include "MMKVPredef.h"
|
|
23
23
|
|
|
24
|
-
#if defined(MMKV_IOS) && defined(__cplusplus)
|
|
25
|
-
|
|
26
24
|
MMKV_NAMESPACE_BEGIN
|
|
27
25
|
|
|
26
|
+
#if defined(MMKV_IOS) && defined(__cplusplus)
|
|
27
|
+
|
|
28
28
|
class MLockPtr {
|
|
29
29
|
size_t m_lockDownSize;
|
|
30
30
|
uint8_t *m_lockedPtr;
|
|
@@ -39,6 +39,8 @@ public:
|
|
|
39
39
|
return (m_lockedPtr != nullptr);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
static bool isMLockPtrEnabled;
|
|
43
|
+
|
|
42
44
|
// just forbid it for possibly misuse
|
|
43
45
|
explicit MLockPtr(const MLockPtr &other) = delete;
|
|
44
46
|
MLockPtr &operator=(const MLockPtr &other) = delete;
|
|
@@ -46,6 +48,10 @@ public:
|
|
|
46
48
|
|
|
47
49
|
std::pair<bool, MLockPtr> guardForBackgroundWriting(void *ptr, size_t size);
|
|
48
50
|
|
|
49
|
-
MMKV_NAMESPACE_END
|
|
50
|
-
|
|
51
51
|
#endif
|
|
52
|
+
|
|
53
|
+
enum { UnKnown = 0, PowerMac = 1, Mac, iPhone, iPod, iPad, AppleTV, AppleWatch };
|
|
54
|
+
|
|
55
|
+
void GetAppleMachineInfo(int &device, int &version);
|
|
56
|
+
|
|
57
|
+
MMKV_NAMESPACE_END
|
package/MMKV/Core/MemoryFile.cpp
CHANGED
|
@@ -49,8 +49,8 @@ File::File(MMKVPath_t path, OpenFlag flag) : m_path(std::move(path)), m_fd(-1),
|
|
|
49
49
|
open();
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
MemoryFile::MemoryFile(MMKVPath_t path) : m_diskFile(std::move(path), OpenFlag::ReadWrite | OpenFlag::Create), m_ptr(nullptr), m_size(0) {
|
|
53
|
-
reloadFromFile();
|
|
52
|
+
MemoryFile::MemoryFile(MMKVPath_t path, size_t expectedCapacity) : m_diskFile(std::move(path), OpenFlag::ReadWrite | OpenFlag::Create), m_ptr(nullptr), m_size(0) {
|
|
53
|
+
reloadFromFile(expectedCapacity);
|
|
54
54
|
}
|
|
55
55
|
# endif // !defined(MMKV_ANDROID)
|
|
56
56
|
|
|
@@ -154,6 +154,16 @@ bool MemoryFile::truncate(size_t size) {
|
|
|
154
154
|
if (!zeroFillFile(m_diskFile.m_fd, oldSize, m_size - oldSize)) {
|
|
155
155
|
MMKVError("fail to zeroFile [%s] to size %zu, %s", m_diskFile.m_path.c_str(), m_size, strerror(errno));
|
|
156
156
|
m_size = oldSize;
|
|
157
|
+
|
|
158
|
+
// redo ftruncate to its previous size
|
|
159
|
+
int status = ::ftruncate(m_diskFile.m_fd, static_cast<off_t>(m_size));
|
|
160
|
+
if (status != 0) {
|
|
161
|
+
MMKVError("failed to truncate back [%s] to size %zu, %s", m_diskFile.m_path.c_str(), m_size, strerror(errno));
|
|
162
|
+
} else {
|
|
163
|
+
MMKVError("success to truncate [%s] back to size %zu", m_diskFile.m_path.c_str(), m_size);
|
|
164
|
+
MMKVError("after truncate, file size = %zu", getActualFileSize());
|
|
165
|
+
}
|
|
166
|
+
|
|
157
167
|
return false;
|
|
158
168
|
}
|
|
159
169
|
}
|
|
@@ -182,17 +192,18 @@ bool MemoryFile::msync(SyncFlag syncFlag) {
|
|
|
182
192
|
}
|
|
183
193
|
|
|
184
194
|
bool MemoryFile::mmap() {
|
|
195
|
+
auto oldPtr = m_ptr;
|
|
185
196
|
m_ptr = (char *) ::mmap(m_ptr, m_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_diskFile.m_fd, 0);
|
|
186
197
|
if (m_ptr == MAP_FAILED) {
|
|
187
198
|
MMKVError("fail to mmap [%s], %s", m_diskFile.m_path.c_str(), strerror(errno));
|
|
188
199
|
m_ptr = nullptr;
|
|
189
200
|
return false;
|
|
190
201
|
}
|
|
191
|
-
|
|
202
|
+
MMKVInfo("mmap to address [%p], oldPtr [%p], [%s]", m_ptr, oldPtr, m_diskFile.m_path.c_str());
|
|
192
203
|
return true;
|
|
193
204
|
}
|
|
194
205
|
|
|
195
|
-
void MemoryFile::reloadFromFile() {
|
|
206
|
+
void MemoryFile::reloadFromFile(size_t expectedCapacity) {
|
|
196
207
|
# ifdef MMKV_ANDROID
|
|
197
208
|
if (m_fileType == MMFILE_TYPE_ASHMEM) {
|
|
198
209
|
return;
|
|
@@ -201,20 +212,25 @@ void MemoryFile::reloadFromFile() {
|
|
|
201
212
|
if (isFileValid()) {
|
|
202
213
|
MMKVWarning("calling reloadFromFile while the cache [%s] is still valid", m_diskFile.m_path.c_str());
|
|
203
214
|
MMKV_ASSERT(0);
|
|
204
|
-
|
|
215
|
+
doCleanMemoryCache(false);
|
|
205
216
|
}
|
|
206
217
|
|
|
207
218
|
if (!m_diskFile.open()) {
|
|
208
219
|
MMKVError("fail to open:%s, %s", m_diskFile.m_path.c_str(), strerror(errno));
|
|
209
220
|
} else {
|
|
210
221
|
FileLock fileLock(m_diskFile.m_fd);
|
|
211
|
-
InterProcessLock lock(&fileLock,
|
|
222
|
+
InterProcessLock lock(&fileLock, SharedLockType);
|
|
212
223
|
SCOPED_LOCK(&lock);
|
|
213
224
|
|
|
214
225
|
mmkv::getFileSize(m_diskFile.m_fd, m_size);
|
|
226
|
+
size_t expectedSize = std::max<size_t>(DEFAULT_MMAP_SIZE, roundUp<size_t>(expectedCapacity, DEFAULT_MMAP_SIZE));
|
|
215
227
|
// round up to (n * pagesize)
|
|
216
|
-
if (m_size <
|
|
217
|
-
|
|
228
|
+
if (m_size < expectedSize || (m_size % DEFAULT_MMAP_SIZE != 0)) {
|
|
229
|
+
InterProcessLock exclusiveLock(&fileLock, ExclusiveLockType);
|
|
230
|
+
SCOPED_LOCK(&exclusiveLock);
|
|
231
|
+
|
|
232
|
+
size_t roundSize = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE;;
|
|
233
|
+
roundSize = std::max<size_t>(expectedSize, roundSize);
|
|
218
234
|
truncate(roundSize);
|
|
219
235
|
} else {
|
|
220
236
|
auto ret = mmap();
|
|
@@ -271,15 +287,19 @@ extern bool mkPath(const MMKVPath_t &str) {
|
|
|
271
287
|
if (stat(path, &sb) != 0) {
|
|
272
288
|
if (errno != ENOENT || mkdir(path, 0777) != 0) {
|
|
273
289
|
MMKVWarning("%s : %s", path, strerror(errno));
|
|
274
|
-
|
|
275
|
-
|
|
290
|
+
// there's report that some Android devices might not have access permission on parent dir
|
|
291
|
+
if (done) {
|
|
292
|
+
free(path);
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
goto LContinue;
|
|
276
296
|
}
|
|
277
297
|
} else if (!S_ISDIR(sb.st_mode)) {
|
|
278
298
|
MMKVWarning("%s: %s", path, strerror(ENOTDIR));
|
|
279
299
|
free(path);
|
|
280
300
|
return false;
|
|
281
301
|
}
|
|
282
|
-
|
|
302
|
+
LContinue:
|
|
283
303
|
*slash = '/';
|
|
284
304
|
}
|
|
285
305
|
free(path);
|
package/MMKV/Core/MemoryFile.h
CHANGED
|
@@ -55,6 +55,11 @@ static inline bool operator & (OpenFlag left, OpenFlag right) {
|
|
|
55
55
|
return ((static_cast<uint32_t>(left) & static_cast<uint32_t>(right)) != 0);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
template <typename T>
|
|
59
|
+
T roundUp(T numToRound, T multiple) {
|
|
60
|
+
return ((numToRound + multiple - 1) / multiple) * multiple;
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
class File {
|
|
59
64
|
MMKVPath_t m_path;
|
|
60
65
|
MMKVFileHandle_t m_fd;
|
|
@@ -110,9 +115,9 @@ class MemoryFile {
|
|
|
110
115
|
|
|
111
116
|
public:
|
|
112
117
|
#ifndef MMKV_ANDROID
|
|
113
|
-
explicit MemoryFile(MMKVPath_t path);
|
|
118
|
+
explicit MemoryFile(MMKVPath_t path, size_t expectedCapacity = 0);
|
|
114
119
|
#else
|
|
115
|
-
MemoryFile(MMKVPath_t path, size_t size, FileType fileType);
|
|
120
|
+
MemoryFile(MMKVPath_t path, size_t size, FileType fileType, size_t expectedCapacity = 0);
|
|
116
121
|
explicit MemoryFile(MMKVFileHandle_t ashmemFD);
|
|
117
122
|
|
|
118
123
|
const FileType m_fileType;
|
|
@@ -137,7 +142,7 @@ public:
|
|
|
137
142
|
bool msync(SyncFlag syncFlag);
|
|
138
143
|
|
|
139
144
|
// call this if clearMemoryCache() has been called
|
|
140
|
-
void reloadFromFile();
|
|
145
|
+
void reloadFromFile(size_t expectedCapacity = 0);
|
|
141
146
|
|
|
142
147
|
void clearMemoryCache() { doCleanMemoryCache(false); }
|
|
143
148
|
|
|
@@ -70,10 +70,10 @@ File::File(MMKVFileHandle_t ashmemFD)
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
MemoryFile::MemoryFile(string path, size_t size, FileType fileType)
|
|
73
|
+
MemoryFile::MemoryFile(string path, size_t size, FileType fileType, size_t expectedCapacity)
|
|
74
74
|
: m_diskFile(std::move(path), OpenFlag::ReadWrite | OpenFlag::Create, size, fileType), m_ptr(nullptr), m_size(0), m_fileType(fileType) {
|
|
75
75
|
if (m_fileType == MMFILE_TYPE_FILE) {
|
|
76
|
-
reloadFromFile();
|
|
76
|
+
reloadFromFile(expectedCapacity);
|
|
77
77
|
} else {
|
|
78
78
|
if (m_diskFile.isFileValid()) {
|
|
79
79
|
m_size = m_diskFile.m_size;
|
|
@@ -53,7 +53,6 @@ void tryResetFileProtection(const string &path) {
|
|
|
53
53
|
#ifdef MMKV_APPLE
|
|
54
54
|
|
|
55
55
|
#include <copyfile.h>
|
|
56
|
-
#include <mach/mach_time.h>
|
|
57
56
|
|
|
58
57
|
namespace mmkv {
|
|
59
58
|
|
|
@@ -85,7 +84,7 @@ bool tryAtomicRename(const char *src, const char *dst) {
|
|
|
85
84
|
|
|
86
85
|
bool copyFile(const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
|
|
87
86
|
// prepare a temp file for atomic rename, avoid data corruption of suddent crash
|
|
88
|
-
NSString *uniqueFileName = [NSString stringWithFormat:@"mmkv_%
|
|
87
|
+
NSString *uniqueFileName = [NSString stringWithFormat:@"mmkv_%zu", (size_t) NSDate.timeIntervalSinceReferenceDate];
|
|
89
88
|
NSString *tmpFile = [NSTemporaryDirectory() stringByAppendingPathComponent:uniqueFileName];
|
|
90
89
|
if (copyfile(srcPath.c_str(), tmpFile.UTF8String, nullptr, COPYFILE_UNLINK | COPYFILE_CLONE) != 0) {
|
|
91
90
|
MMKVError("fail to copyfile [%s] to [%s], %s", srcPath.c_str(), tmpFile.UTF8String, strerror(errno));
|
|
@@ -125,7 +124,7 @@ bool copyFileContent(const MMKVPath_t &srcPath, MMKVFileHandle_t dstFD) {
|
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
// sendfile() equivalent
|
|
128
|
-
if (::fcopyfile(srcFile.getFd(), dstFD, nullptr,
|
|
127
|
+
if (::fcopyfile(srcFile.getFd(), dstFD, nullptr, COPYFILE_ALL) == 0) {
|
|
129
128
|
MMKVInfo("copy content from %s to fd[%d] finish", srcPath.c_str(), dstFD);
|
|
130
129
|
return true;
|
|
131
130
|
}
|
|
@@ -94,12 +94,12 @@ size_t File::getActualFileSize() const {
|
|
|
94
94
|
return size;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
MemoryFile::MemoryFile(MMKVPath_t path)
|
|
97
|
+
MemoryFile::MemoryFile(MMKVPath_t path, size_t expectedCapacity)
|
|
98
98
|
: m_diskFile(std::move(path), OpenFlag::ReadWrite | OpenFlag::Create)
|
|
99
99
|
, m_fileMapping(nullptr)
|
|
100
100
|
, m_ptr(nullptr)
|
|
101
101
|
, m_size(0) {
|
|
102
|
-
reloadFromFile();
|
|
102
|
+
reloadFromFile(expectedCapacity);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
bool MemoryFile::truncate(size_t size) {
|
|
@@ -178,12 +178,13 @@ bool MemoryFile::mmap() {
|
|
|
178
178
|
MMKVError("fail to mmap [%ls], %d", m_diskFile.m_path.c_str(), GetLastError());
|
|
179
179
|
return false;
|
|
180
180
|
}
|
|
181
|
+
MMKVInfo("mmap to address [%p], [%ls]", m_ptr, m_diskFile.m_path.c_str());
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
return true;
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
void MemoryFile::reloadFromFile() {
|
|
187
|
+
void MemoryFile::reloadFromFile(size_t expectedCapacity) {
|
|
187
188
|
if (isFileValid()) {
|
|
188
189
|
MMKVWarning("calling reloadFromFile while the cache [%ls] is still valid", m_diskFile.m_path.c_str());
|
|
189
190
|
assert(0);
|
|
@@ -196,9 +197,11 @@ void MemoryFile::reloadFromFile() {
|
|
|
196
197
|
SCOPED_LOCK(&lock);
|
|
197
198
|
|
|
198
199
|
mmkv::getFileSize(m_diskFile.getFd(), m_size);
|
|
200
|
+
size_t expectedSize = std::max<size_t>(DEFAULT_MMAP_SIZE, roundUp<size_t>(expectedCapacity, DEFAULT_MMAP_SIZE));
|
|
199
201
|
// round up to (n * pagesize)
|
|
200
|
-
if (m_size <
|
|
201
|
-
size_t roundSize = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE
|
|
202
|
+
if (m_size < expectedSize || (m_size % DEFAULT_MMAP_SIZE != 0)) {
|
|
203
|
+
size_t roundSize = ((m_size / DEFAULT_MMAP_SIZE) + 1) * DEFAULT_MMAP_SIZE;;
|
|
204
|
+
roundSize = std::max<size_t>(expectedSize, roundSize);
|
|
202
205
|
truncate(roundSize);
|
|
203
206
|
} else {
|
|
204
207
|
auto ret = mmap();
|
|
@@ -188,6 +188,9 @@ MMBuffer MiniPBCoder::encodeDataWithObject(const MMBuffer &obj) {
|
|
|
188
188
|
} catch (const std::exception &exception) {
|
|
189
189
|
MMKVError("%s", exception.what());
|
|
190
190
|
return MMBuffer();
|
|
191
|
+
} catch (...) {
|
|
192
|
+
MMKVError("prepare encode fail");
|
|
193
|
+
return MMBuffer();
|
|
191
194
|
}
|
|
192
195
|
}
|
|
193
196
|
|
|
@@ -271,6 +274,8 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t position, bool greedy) {
|
|
|
271
274
|
block(dic);
|
|
272
275
|
} catch (std::exception &exception) {
|
|
273
276
|
MMKVError("%s", exception.what());
|
|
277
|
+
} catch (...) {
|
|
278
|
+
MMKVError("prepare encode fail");
|
|
274
279
|
}
|
|
275
280
|
} else {
|
|
276
281
|
try {
|
|
@@ -279,6 +284,8 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t position, bool greedy) {
|
|
|
279
284
|
dic.swap(tmpDic);
|
|
280
285
|
} catch (std::exception &exception) {
|
|
281
286
|
MMKVError("%s", exception.what());
|
|
287
|
+
} catch (...) {
|
|
288
|
+
MMKVError("prepare encode fail");
|
|
282
289
|
}
|
|
283
290
|
}
|
|
284
291
|
}
|
|
@@ -314,6 +321,8 @@ void MiniPBCoder::decodeOneMap(MMKVMapCrypt &dic, size_t position, bool greedy)
|
|
|
314
321
|
block(dic);
|
|
315
322
|
} catch (std::exception &exception) {
|
|
316
323
|
MMKVError("%s", exception.what());
|
|
324
|
+
} catch (...) {
|
|
325
|
+
MMKVError("prepare encode fail");
|
|
317
326
|
}
|
|
318
327
|
} else {
|
|
319
328
|
try {
|
|
@@ -322,6 +331,8 @@ void MiniPBCoder::decodeOneMap(MMKVMapCrypt &dic, size_t position, bool greedy)
|
|
|
322
331
|
dic.swap(tmpDic);
|
|
323
332
|
} catch (std::exception &exception) {
|
|
324
333
|
MMKVError("%s", exception.what());
|
|
334
|
+
} catch (...) {
|
|
335
|
+
MMKVError("prepare encode fail");
|
|
325
336
|
}
|
|
326
337
|
}
|
|
327
338
|
}
|
package/MMKV/Core/MiniPBCoder.h
CHANGED
|
@@ -111,6 +111,8 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t position, bool greedy) {
|
|
|
111
111
|
block(dic);
|
|
112
112
|
} catch (std::exception &exception) {
|
|
113
113
|
MMKVError("%s", exception.what());
|
|
114
|
+
} catch (...) {
|
|
115
|
+
MMKVError("decode fail");
|
|
114
116
|
}
|
|
115
117
|
} else {
|
|
116
118
|
try {
|
|
@@ -122,6 +124,8 @@ void MiniPBCoder::decodeOneMap(MMKVMap &dic, size_t position, bool greedy) {
|
|
|
122
124
|
}
|
|
123
125
|
} catch (std::exception &exception) {
|
|
124
126
|
MMKVError("%s", exception.what());
|
|
127
|
+
} catch (...) {
|
|
128
|
+
MMKVError("decode fail");
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
131
|
}
|
|
@@ -164,6 +168,8 @@ void MiniPBCoder::decodeOneMap(MMKVMapCrypt &dic, size_t position, bool greedy)
|
|
|
164
168
|
block(dic);
|
|
165
169
|
} catch (std::exception &exception) {
|
|
166
170
|
MMKVError("%s", exception.what());
|
|
171
|
+
} catch (...) {
|
|
172
|
+
MMKVError("decode fail");
|
|
167
173
|
}
|
|
168
174
|
} else {
|
|
169
175
|
try {
|
|
@@ -175,6 +181,8 @@ void MiniPBCoder::decodeOneMap(MMKVMapCrypt &dic, size_t position, bool greedy)
|
|
|
175
181
|
}
|
|
176
182
|
} catch (std::exception &exception) {
|
|
177
183
|
MMKVError("%s", exception.what());
|
|
184
|
+
} catch (...) {
|
|
185
|
+
MMKVError("decode fail");
|
|
178
186
|
}
|
|
179
187
|
}
|
|
180
188
|
}
|
package/MMKV/Core/ThreadLock.cpp
CHANGED
|
@@ -59,6 +59,11 @@ void ThreadLock::unlock() {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
bool ThreadLock::try_lock() {
|
|
63
|
+
auto ret = pthread_mutex_trylock(&m_lock);
|
|
64
|
+
return (ret == 0);
|
|
65
|
+
}
|
|
66
|
+
|
|
62
67
|
void ThreadLock::ThreadOnce(ThreadOnceToken_t *onceToken, void (*callback)()) {
|
|
63
68
|
pthread_once(onceToken, callback);
|
|
64
69
|
}
|
package/MMKV/Core/ThreadLock.h
CHANGED
|
@@ -161,7 +161,9 @@ AES_Te:
|
|
|
161
161
|
|
|
162
162
|
/* void openssl_aes_arm_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
|
163
163
|
*/
|
|
164
|
+
#ifndef __APPLE__
|
|
164
165
|
.type openssl_aes_arm_encrypt, %function
|
|
166
|
+
#endif
|
|
165
167
|
#ifndef __linux__
|
|
166
168
|
.globl _openssl_aes_arm_encrypt
|
|
167
169
|
#ifdef __thumb2__
|
|
@@ -423,7 +425,9 @@ Lenc_loop:
|
|
|
423
425
|
ldr pc,[sp],#4 // pop and return
|
|
424
426
|
|
|
425
427
|
|
|
428
|
+
#ifndef __APPLE__
|
|
426
429
|
.type openssl_aes_arm_set_encrypt_key, %function
|
|
430
|
+
#endif
|
|
427
431
|
#ifndef __linux__
|
|
428
432
|
.globl _openssl_aes_arm_set_encrypt_key
|
|
429
433
|
#ifdef __thumb2__
|
|
@@ -737,7 +741,9 @@ Labrt:
|
|
|
737
741
|
.word 0xe12fff1e // interoperable with Thumb ISA:-)
|
|
738
742
|
#endif
|
|
739
743
|
|
|
744
|
+
#ifndef __APPLE__
|
|
740
745
|
.type openssl_aes_arm_set_decrypt_key, %function
|
|
746
|
+
#endif
|
|
741
747
|
#ifndef __linux__
|
|
742
748
|
.globl _openssl_aes_arm_set_decrypt_key
|
|
743
749
|
#ifdef __thumb2__
|
|
@@ -957,7 +963,9 @@ AES_Td:
|
|
|
957
963
|
.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
|
958
964
|
|
|
959
965
|
|
|
966
|
+
#ifndef __APPLE__
|
|
960
967
|
.type openssl_aes_arm_decrypt, %function
|
|
968
|
+
#endif
|
|
961
969
|
// void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
|
962
970
|
#ifndef __linux__
|
|
963
971
|
.globl _openssl_aes_arm_decrypt
|
package/MMKV/Core/core.vcxproj
CHANGED
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
</ItemGroup>
|
|
66
66
|
<PropertyGroup Label="Globals">
|
|
67
67
|
<ProjectGuid>{32CD39C9-37B5-3D38-A3D9-45E13F4AF9C5}</ProjectGuid>
|
|
68
|
-
<WindowsTargetPlatformVersion>10.0
|
|
68
|
+
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
|
69
69
|
<Keyword>Win32Proj</Keyword>
|
|
70
70
|
<Platform>Win32</Platform>
|
|
71
71
|
<ProjectName>core</ProjectName>
|
|
@@ -75,12 +75,12 @@
|
|
|
75
75
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
|
76
76
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
77
77
|
<CharacterSet>Unicode</CharacterSet>
|
|
78
|
-
<PlatformToolset>
|
|
78
|
+
<PlatformToolset>v143</PlatformToolset>
|
|
79
79
|
</PropertyGroup>
|
|
80
80
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
|
81
81
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
|
82
82
|
<CharacterSet>Unicode</CharacterSet>
|
|
83
|
-
<PlatformToolset>
|
|
83
|
+
<PlatformToolset>v143</PlatformToolset>
|
|
84
84
|
</PropertyGroup>
|
|
85
85
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
86
86
|
<ImportGroup Label="ExtensionSettings">
|
package/MMKV/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[](https://github.com/Tencent/MMKV/blob/master/LICENSE.TXT)
|
|
2
2
|
[](https://github.com/Tencent/MMKV/pulls)
|
|
3
|
-
[](https://github.com/Tencent/MMKV/releases)
|
|
4
4
|
[](https://github.com/Tencent/MMKV/wiki/home)
|
|
5
5
|
|
|
6
6
|
中文版本请参看[这里](./README_CN.md)
|
|
@@ -28,8 +28,8 @@ Add the following lines to `build.gradle` on your app module:
|
|
|
28
28
|
|
|
29
29
|
```gradle
|
|
30
30
|
dependencies {
|
|
31
|
-
implementation 'com.tencent:mmkv:1.3.
|
|
32
|
-
// replace "1.3.
|
|
31
|
+
implementation 'com.tencent:mmkv:1.3.3'
|
|
32
|
+
// replace "1.3.3" with any available version
|
|
33
33
|
}
|
|
34
34
|
```
|
|
35
35
|
|
package/android/build.gradle
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import com.android.Version
|
|
2
|
+
|
|
3
|
+
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
|
|
4
|
+
def agpVersionMajor = agpVersion.tokenize('.')[0].toInteger()
|
|
5
|
+
def androidManifestPath = agpVersionMajor >= 7 ? 'src/main/AndroidManifest.xml' : 'src/hasNamespace/AndroidManifest.xml'
|
|
6
|
+
|
|
1
7
|
buildscript {
|
|
2
8
|
repositories {
|
|
3
9
|
maven {
|
|
@@ -46,16 +52,23 @@ repositories {
|
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
android {
|
|
49
|
-
namespace = "com.reactnativemmkv"
|
|
50
55
|
compileSdkVersion safeExtGet("compileSdkVersion", 28)
|
|
51
|
-
|
|
56
|
+
if (agpVersionMajor >= 7) {
|
|
57
|
+
namespace = "com.reactnativemmkv"
|
|
58
|
+
}
|
|
52
59
|
|
|
53
|
-
if (
|
|
60
|
+
if (agpVersionMajor >= 8) {
|
|
54
61
|
buildFeatures {
|
|
55
62
|
buildConfig = true
|
|
56
63
|
}
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
sourceSets {
|
|
67
|
+
main {
|
|
68
|
+
manifest.srcFile androidManifestPath
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
// Used to override the NDK path/version on internal CI or by allowing
|
|
60
73
|
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
|
61
74
|
if (rootProject.hasProperty("ndkPath")) {
|
|
@@ -66,7 +66,13 @@ extern "C" JNIEXPORT void JNICALL Java_com_reactnativemmkv_MmkvModule_nativeInst
|
|
|
66
66
|
jobject clazz,
|
|
67
67
|
jlong jsiPtr,
|
|
68
68
|
jstring path) {
|
|
69
|
-
|
|
69
|
+
#if DEBUG
|
|
70
|
+
MMKVLogLevel logLevel = MMKVLogDebug;
|
|
71
|
+
#else
|
|
72
|
+
MMKVLogLevel logLevel = MMKVLogError;
|
|
73
|
+
#endif
|
|
74
|
+
std::string storageDirectory = jstringToStdString(env, path);
|
|
75
|
+
MMKV::initializeMMKV(storageDirectory, logLevel);
|
|
70
76
|
|
|
71
77
|
auto runtime = reinterpret_cast<jsi::Runtime*>(jsiPtr);
|
|
72
78
|
if (runtime) {
|