Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.0.11 #74

Merged
merged 17 commits into from
Oct 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Android/MMKV/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx1536m
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

VERSION_NAME_PREFIX=1.0.10
VERSION_NAME_PREFIX=1.0.11
#VERSION_NAME_SUFFIX=-SNAPSHOT
VERSION_NAME_SUFFIX=
41 changes: 38 additions & 3 deletions Android/MMKV/mmkv/src/main/java/com/tencent/mmkv/MMKV.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ public class MMKV implements SharedPreferences, SharedPreferences.Editor {
}

// call on program start
static private String rootDir = null;
public static String initialize(Context context) {
String rootDir = context.getFilesDir().getAbsolutePath() + "/mmkv";
rootDir = context.getFilesDir().getAbsolutePath() + "/mmkv";
initialize(rootDir);
return rootDir;
}
Expand All @@ -56,17 +57,32 @@ public static String initialize(Context context) {
static private final int ASHMEM_MODE = 0x4;

public static MMKV mmkvWithID(String mmapID) {
if (rootDir == null) {
throw new IllegalStateException("You should Call MMKV.initialize() first.");
}
verifyMMID(mmapID);

long handle = getMMKVWithID(mmapID, SINGLE_PROCESS_MODE, null);
return new MMKV(handle);
}

public static MMKV mmkvWithID(String mmapID, int mode) {
if (rootDir == null) {
throw new IllegalStateException("You should Call MMKV.initialize() first.");
}
verifyMMID(mmapID);

long handle = getMMKVWithID(mmapID, mode, null);
return new MMKV(handle);
}

// cryptKey's length <= 16
public static MMKV mmkvWithID(String mmapID, int mode, String cryptKey) {
if (rootDir == null) {
throw new IllegalStateException("You should Call MMKV.initialize() first.");
}
verifyMMID(mmapID);

long handle = getMMKVWithID(mmapID, mode, cryptKey);
return new MMKV(handle);
}
Expand All @@ -76,6 +92,11 @@ public static MMKV mmkvWithID(String mmapID, int mode, String cryptKey) {
@Nullable
public static MMKV
mmkvWithAshmemID(Context context, String mmapID, int size, int mode, String cryptKey) {
if (rootDir == null) {
throw new IllegalStateException("You should Call MMKV.initialize() first.");
}
verifyMMID(mmapID);

String processName =
MMKVContentProvider.getProcessNameByPID(context, android.os.Process.myPid());
if (processName == null || processName.length() == 0) {
Expand Down Expand Up @@ -104,8 +125,8 @@ public static MMKV mmkvWithID(String mmapID, int mode, String cryptKey) {
if (parcelableMMKV != null) {
MMKV mmkv = parcelableMMKV.toMMKV();
if (mmkv != null) {
System.out.println(mmkv.mmapID() + " fd = " + mmkv.ashmemFD()
+ ", meta fd = " + mmkv.ashmemMetaFD());
System.out.println(mmkv.mmapID() + " fd = " + mmkv.ashmemFD() +
", meta fd = " + mmkv.ashmemMetaFD());
}
return mmkv;
}
Expand All @@ -120,12 +141,26 @@ public static MMKV mmkvWithID(String mmapID, int mode, String cryptKey) {
return null;
}

private static void verifyMMID(String mmapID) {
if (mmapID.indexOf('/') >= 0) {
throw new IllegalArgumentException("\"/\" is not allowed inside mmapID");
}
}

public static MMKV defaultMMKV() {
if (rootDir == null) {
throw new IllegalStateException("You should Call MMKV.initialize() first.");
}

long handle = getDefaultMMKV(SINGLE_PROCESS_MODE, null);
return new MMKV(handle);
}

public static MMKV defaultMMKV(int mode, String cryptKey) {
if (rootDir == null) {
throw new IllegalStateException("You should Call MMKV.initialize() first.");
}

long handle = getDefaultMMKV(mode, cryptKey);
return new MMKV(handle);
}
Expand Down
2 changes: 1 addition & 1 deletion Android/MMKV/mmkvdemo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dependencies {
// implementation project(':mmkv')
implementation 'com.tencent:mmkv:1.0.10'
// implementation 'com.tencent:mmkv:1.0.10-SNAPSHOT'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#MMKV Change Log

##v1.0.11 / 2018-10-12
### iOS / macOS
What's new

* Port to **macOS**
* Support **NSCoding**
You can store NSArray/NSDictionary or any object what implements `<NSCoding>` protocol.
* Redesign Swift interface
* Some performance improvement

Known Issues

* MMKV use mmapID as its filename, so don't contain any `/` inside mmapID.
* Storing a value of `type A` and getting by `type B` may not work. MMKV does type erasure while storing values. That means it's hard for MMKV to do value-type-checking, if not impossible.

### Android
What's new

* Some performance improvement

Known Issues

* Getting a MMKV instance with mmapID that contains `/` may fail.
MMKV uses mmapID as its filename, so don't contain any `/` inside mmapID.
* Storing a value of `type A` and getting by `type B` may not work.
MMKV does type erasure while storing values. That means it's hard for MMKV to do value-type-checking, if not impossible.
* `registerOnSharedPreferenceChangeListener` not supported.
This is intended. We believe doing data-change-listener inside a storage framework smells really bad to us. We suggest using something like event-bus to notify any interesting clients.

##v1.0.10 / 2018-09-21

* Initial Release
2 changes: 1 addition & 1 deletion MMKV.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "MMKV"
s.version = "1.0.10"
s.version = "1.0.11"
s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat."

s.description = <<-DESC
Expand Down
56 changes: 52 additions & 4 deletions iOS/MMKV/MMKV.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
CB1FD4C520469B8800931B5F /* MiniPBUtility.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD4C020469B8800931B5F /* MiniPBUtility.mm */; };
CB1FD4C620469B8800931B5F /* MiniPBCoder.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD4C220469B8800931B5F /* MiniPBCoder.mm */; };
CB1FD4CD2046ACBC00931B5F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4CC2046ACBC00931B5F /* Foundation.framework */; };
CB1FD4CF2046ACC100931B5F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4CE2046ACC100931B5F /* UIKit.framework */; };
CB6DEFA9212E6F010024F0E8 /* AESCrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = CB6DEF9F212E6F010024F0E8 /* AESCrypt.h */; };
CB6DEFAA212E6F010024F0E8 /* opensslconf.h in Headers */ = {isa = PBXBuildFile; fileRef = CB6DEFA1212E6F010024F0E8 /* opensslconf.h */; };
CB6DEFAB212E6F010024F0E8 /* cfb128.c in Sources */ = {isa = PBXBuildFile; fileRef = CB6DEFA2212E6F010024F0E8 /* cfb128.c */; };
Expand All @@ -38,7 +37,6 @@
CBC1A90120DA948A00AD5087 /* MiniPBUtility.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD4C020469B8800931B5F /* MiniPBUtility.mm */; };
CBC1A90220DA948A00AD5087 /* MMKV.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB1FD4952046984F00931B5F /* MMKV.mm */; };
CBC1A90420DA94A000AD5087 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CBC1A90320DA94A000AD5087 /* libz.tbd */; };
CBC1A90520DA94AD00AD5087 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4CE2046ACC100931B5F /* UIKit.framework */; };
CBC1A90620DA94B900AD5087 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB1FD4CC2046ACBC00931B5F /* Foundation.framework */; };
CBC1A90C20DA97DF00AD5087 /* MMKV.h in Headers */ = {isa = PBXBuildFile; fileRef = CB1FD4942046984F00931B5F /* MMKV.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -95,7 +93,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CB1FD4CF2046ACC100931B5F /* UIKit.framework in Frameworks */,
CB1FD4CD2046ACBC00931B5F /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -105,7 +102,6 @@
buildActionMask = 2147483647;
files = (
CBC1A90620DA94B900AD5087 /* Foundation.framework in Frameworks */,
CBC1A90520DA94AD00AD5087 /* UIKit.framework in Frameworks */,
CBC1A90420DA94A000AD5087 /* libz.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -393,6 +389,10 @@
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
VALID_ARCHS = "arm64 armv7 x86_64";
"VALID_ARCHS[sdk=iphoneos*]" = "arm64 armv7";
"VALID_ARCHS[sdk=macosx*]" = x86_64;
};
name = Debug;
};
Expand Down Expand Up @@ -443,31 +443,59 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx";
VALIDATE_PRODUCT = YES;
VALID_ARCHS = "arm64 armv7 x86_64";
"VALID_ARCHS[sdk=iphoneos*]" = "arm64 armv7";
"VALID_ARCHS[sdk=macosx*]" = x86_64;
};
name = Release;
};
CB1FD49B2046984F00931B5F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
MACOSX_DEPLOYMENT_TARGET = 10.9;
OTHER_LDFLAGS = "-ObjC";
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-ObjC",
"-framework",
UIKit,
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-ObjC",
"-framework",
UIKit,
);
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 armv7";
"VALID_ARCHS[sdk=macosx*]" = x86_64;
};
name = Debug;
};
CB1FD49C2046984F00931B5F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
MACOSX_DEPLOYMENT_TARGET = 10.9;
OTHER_LDFLAGS = "-ObjC";
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-ObjC",
"-framework",
UIKit,
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-ObjC",
"-framework",
UIKit,
);
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 armv7";
"VALID_ARCHS[sdk=macosx*]" = x86_64;
};
name = Release;
};
Expand All @@ -488,11 +516,21 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.9;
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-framework",
UIKit,
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-framework",
UIKit,
);
PRODUCT_BUNDLE_IDENTIFIER = com.tencent.MMKV;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 armv7";
"VALID_ARCHS[sdk=macosx*]" = x86_64;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
Expand All @@ -515,11 +553,21 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.9;
"OTHER_LDFLAGS[sdk=iphoneos*]" = (
"-framework",
UIKit,
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-framework",
UIKit,
);
PRODUCT_BUNDLE_IDENTIFIER = com.tencent.MMKV;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "arm64 armv7";
"VALID_ARCHS[sdk=macosx*]" = x86_64;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
Expand Down
30 changes: 19 additions & 11 deletions iOS/MMKV/MMKV/MMKV.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
#import "MiniPBCoder.h"
#import "MiniPBUtility.h"
#import "ScopedLock.hpp"

#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
#import <UIKit/UIKit.h>
#endif

#import <algorithm>
#import <sys/mman.h>
#import <sys/stat.h>
Expand Down Expand Up @@ -65,13 +69,10 @@ @implementation MMKV {

+ (void)initialize {
if (self == MMKV.class) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
g_instanceDic = [NSMutableDictionary dictionary];
g_instanceLock = [[NSRecursiveLock alloc] init];

MMKVInfo(@"pagesize:%d", DEFAULT_MMAP_SIZE);
});
g_instanceDic = [NSMutableDictionary dictionary];
g_instanceLock = [[NSRecursiveLock alloc] init];

MMKVInfo(@"pagesize:%d", DEFAULT_MMAP_SIZE);
}
}

Expand Down Expand Up @@ -127,6 +128,7 @@ - (instancetype)initWithMMapID:(NSString *)mmapID cryptKey:(NSData *)cryptKey {

[self loadFromFile];

#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
auto appState = [UIApplication sharedApplication].applicationState;
if (appState == UIApplicationStateBackground) {
m_isInBackground = YES;
Expand All @@ -138,6 +140,7 @@ - (instancetype)initWithMMapID:(NSString *)mmapID cryptKey:(NSData *)cryptKey {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
#endif
}
return self;
}
Expand Down Expand Up @@ -184,6 +187,7 @@ - (void)onMemoryWarning {
[self clearMemoryCache];
}

#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
- (void)didEnterBackground {
CScopedLock lock(m_lock);

Expand All @@ -197,6 +201,7 @@ - (void)didBecomeActive {
m_isInBackground = NO;
MMKVInfo(@"m_isInBackground:%d", m_isInBackground);
}
#endif

#pragma mark - really dirty work

Expand Down Expand Up @@ -1115,15 +1120,18 @@ - (void)removeValuesForKeys:(NSArray *)arrKeys {
[self fullWriteback];
}

#pragma mark - borning stuff
#pragma mark - Boring stuff

- (void)sync {
CScopedLock lock(m_lock);
if (m_needLoadFromFile || ![self isFileValid]) {
if (m_needLoadFromFile || ![self isFileValid] || m_crcPtr == nullptr) {
return;
}
if (msync(m_ptr, m_size, MS_SYNC) != 0) {
MMKVError(@"fail to msync [%@]:%s", m_mmapID, strerror(errno));
if (msync(m_ptr, m_actualSize, MS_SYNC) != 0) {
MMKVError(@"fail to msync data file of [%@]:%s", m_mmapID, strerror(errno));
}
if (msync(m_crcPtr, CRC_FILE_SIZE, MS_SYNC) != 0) {
MMKVError(@"fail to msync crc-32 file of [%@]:%s", m_mmapID, strerror(errno));
}
}

Expand Down
Loading