Skip to content

Commit

Permalink
Merge pull request Tencent#273 from Tencent/dev
Browse files Browse the repository at this point in the history
v1.0.20
  • Loading branch information
lingol authored Jun 5, 2019
2 parents c2e71b4 + f9a14f1 commit a4f7f49
Show file tree
Hide file tree
Showing 31 changed files with 453 additions and 298 deletions.
2 changes: 1 addition & 1 deletion Android/MMKV/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.1'
classpath 'digital.wup:android-maven-publish:3.6.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
Expand Down
4 changes: 3 additions & 1 deletion Android/MMKV/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

VERSION_NAME_PREFIX=1.0.19
VERSION_NAME_PREFIX=1.0.20
#VERSION_NAME_SUFFIX=-SNAPSHOT
VERSION_NAME_SUFFIX=
4 changes: 2 additions & 2 deletions Android/MMKV/gradle/android-publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ android.libraryVariants.all { variant ->
}

// require gradle 4.x +
if (GradleVersion.current() < GradleVersion.version('4.0')) {
/*if (GradleVersion.current() < GradleVersion.version('4.0')) {
throw new GradleException('android-publish.gradle need Gradle 4.0 or newer')
}
}*/

// For bintrayUpload
def publicationName = "component${variant.name.capitalize()}"
Expand Down
4 changes: 2 additions & 2 deletions Android/MMKV/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Apr 04 16:56:29 CST 2018
#Wed May 08 16:12:37 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
10 changes: 5 additions & 5 deletions Android/MMKV/mmkv/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ android {
// defaultPublishConfig "StaticCppRelease"
defaultPublishConfig "SharedCppRelease"
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++1z -fno-exceptions"
Expand All @@ -19,7 +19,7 @@ android {
minifyEnabled false
externalNativeBuild {
cmake {
cppFlags "-fvisibility=hidden", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables"
cppFlags "-fvisibility=hidden", "-funwind-tables", "-fasynchronous-unwind-tables"
}
}
consumerProguardFiles 'proguard-rules.pro'
Expand Down Expand Up @@ -61,8 +61,8 @@ android {

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'androidx.annotation:annotation:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import androidx.test.InstrumentationRegistry;

import org.junit.AfterClass;
import org.junit.BeforeClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import android.content.Intent;
import android.os.IBinder;
import android.os.Process;
import android.support.annotation.Nullable;
import androidx.annotation.Nullable;

public class MMKVTestService extends Service {
public static final String SharedMMKVID = "SharedMMKVID";
Expand Down
10 changes: 10 additions & 0 deletions Android/MMKV/mmkv/src/main/cpp/CodedOutputData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ void CodedOutputData::writeBool(bool value) {

void CodedOutputData::writeString(const string &value) {
size_t numberOfBytes = value.size();
if (m_position + numberOfBytes > m_size) {
MMKVError("m_position: %d, numberOfBytes: %zd, m_size: %zd", m_position, numberOfBytes,
m_size);
return;
}
this->writeRawVarint32((int32_t) numberOfBytes);
memcpy(m_ptr + m_position, ((uint8_t *) value.data()), numberOfBytes);
m_position += numberOfBytes;
Expand Down Expand Up @@ -93,6 +98,11 @@ void CodedOutputData::writeRawByte(uint8_t value) {

void CodedOutputData::writeRawData(const MMBuffer &data) {
size_t numberOfBytes = data.length();
if (m_position + numberOfBytes > m_size) {
MMKVError("m_position: %d, numberOfBytes: %zd, m_size: %zd", m_position, numberOfBytes,
m_size);
return;
}
memcpy(m_ptr + m_position, data.getPtr(), numberOfBytes);
m_position += numberOfBytes;
}
Expand Down
38 changes: 15 additions & 23 deletions Android/MMKV/mmkv/src/main/cpp/InterProcessLock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,20 @@

#include "InterProcessLock.h"
#include "MMKVLog.h"
#include <sys/file.h>
#include <unistd.h>

static short LockType2FlockType(LockType lockType) {
static int LockType2FlockType(LockType lockType) {
switch (lockType) {
case SharedLockType:
return F_RDLCK;
return LOCK_SH;
case ExclusiveLockType:
return F_WRLCK;
return LOCK_EX;
}
return LOCK_EX;
}

FileLock::FileLock(int fd) : m_fd(fd), m_sharedLockCount(0), m_exclusiveLockCount(0) {
m_lockInfo.l_type = F_WRLCK;
m_lockInfo.l_start = 0;
m_lockInfo.l_whence = SEEK_SET;
m_lockInfo.l_len = 0;
m_lockInfo.l_pid = 0;
}

bool FileLock::doLock(LockType lockType, int cmd) {
bool FileLock::doLock(LockType lockType, bool wait) {
if (!isFileLockValid()) {
return false;
}
Expand All @@ -63,25 +57,23 @@ bool FileLock::doLock(LockType lockType, int cmd) {
}
}

m_lockInfo.l_type = LockType2FlockType(lockType);
int realLockType = LockType2FlockType(lockType);
int cmd = wait ? realLockType : (realLockType | LOCK_NB);
if (unLockFirstIfNeeded) {
// try lock
auto ret = fcntl(m_fd, F_SETLK, &m_lockInfo);
auto ret = flock(m_fd, realLockType | LOCK_NB);
if (ret == 0) {
return true;
}
// lets be gentleman: unlock my shared-lock to prevent deadlock
auto type = m_lockInfo.l_type;
m_lockInfo.l_type = F_UNLCK;
ret = fcntl(m_fd, F_SETLK, &m_lockInfo);
ret = flock(m_fd, LOCK_UN);
if (ret != 0) {
MMKVError("fail to try unlock first fd=%d, ret=%d, error:%s", m_fd, ret,
strerror(errno));
}
m_lockInfo.l_type = type;
}

auto ret = fcntl(m_fd, cmd, &m_lockInfo);
auto ret = flock(m_fd, cmd);
if (ret != 0) {
MMKVError("fail to lock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
return false;
Expand All @@ -91,11 +83,11 @@ bool FileLock::doLock(LockType lockType, int cmd) {
}

bool FileLock::lock(LockType lockType) {
return doLock(lockType, F_SETLKW);
return doLock(lockType, true);
}

bool FileLock::try_lock(LockType lockType) {
return doLock(lockType, F_SETLK);
return doLock(lockType, false);
}

bool FileLock::unlock(LockType lockType) {
Expand Down Expand Up @@ -127,8 +119,8 @@ bool FileLock::unlock(LockType lockType) {
}
}

m_lockInfo.l_type = static_cast<short>(unlockToSharedLock ? F_RDLCK : F_UNLCK);
auto ret = fcntl(m_fd, F_SETLK, &m_lockInfo);
int cmd = unlockToSharedLock ? LOCK_SH : LOCK_UN;
auto ret = flock(m_fd, cmd);
if (ret != 0) {
MMKVError("fail to unlock fd=%d, ret=%d, error:%s", m_fd, ret, strerror(errno));
return false;
Expand Down
5 changes: 2 additions & 3 deletions Android/MMKV/mmkv/src/main/cpp/InterProcessLock.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ enum LockType {
// handles lock upgrade & downgrade correctly
class FileLock {
int m_fd;
struct flock m_lockInfo;
size_t m_sharedLockCount;
size_t m_exclusiveLockCount;

bool doLock(LockType lockType, int cmd);
bool doLock(LockType lockType, bool wait);

bool isFileLockValid() { return m_fd >= 0; }

Expand All @@ -47,7 +46,7 @@ class FileLock {
FileLock &operator=(const FileLock &other) = delete;

public:
FileLock(int fd);
FileLock(int fd) : m_fd(fd), m_sharedLockCount(0), m_exclusiveLockCount(0) {}

bool lock(LockType lockType);

Expand Down
72 changes: 34 additions & 38 deletions Android/MMKV/mmkv/src/main/cpp/MMKV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,14 @@ void MMKV::loadFromFile() {
if (checkFileCRCValid()) {
loadFromFile = true;
} else {
auto strategic = onMMKVCRCCheckFail(m_mmapID);
auto strategic = mmkv::onMMKVCRCCheckFail(m_mmapID);
if (strategic == OnErrorRecover) {
loadFromFile = true;
needFullWriteback = true;
}
}
} else {
auto strategic = onMMKVFileLengthError(m_mmapID);
auto strategic = mmkv::onMMKVFileLengthError(m_mmapID);
if (strategic == OnErrorRecover) {
writeAcutalSize(m_size - Fixed32Size);
loadFromFile = true;
Expand Down Expand Up @@ -633,7 +633,7 @@ void MMKV::trim() {

fullWriteback();
auto oldSize = m_size;
while (m_size > (m_actualSize * 2)) {
while (m_size > (m_actualSize + Fixed32Size) * 2) {
m_size /= 2;
}
if (oldSize == m_size) {
Expand All @@ -642,7 +642,8 @@ void MMKV::trim() {
return;
}

MMKVInfo("trimming %s from %zu to %zu", m_mmapID.c_str(), oldSize, m_size);
MMKVInfo("trimming %s from %zu to %zu, actualSize %zu", m_mmapID.c_str(), oldSize, m_size,
m_actualSize);

if (ftruncate(m_fd, m_size) != 0) {
MMKVError("fail to truncate [%s] to size %zu, %s", m_mmapID.c_str(), m_size,
Expand Down Expand Up @@ -676,7 +677,7 @@ bool MMKV::ensureMemorySize(size_t newSize) {
if (newSize >= m_output->spaceLeft()) {
// try a full rewrite to make space
static const int offset = pbFixed32Size(0);
MMBuffer data = MiniPBCoder::encodeDataWithObject(m_dic);
MMBuffer data = m_dic.empty() ? MMBuffer(0) : MiniPBCoder::encodeDataWithObject(m_dic);
size_t lenNeeded = data.length() + offset + newSize;
if (m_isAshmem) {
if (lenNeeded > m_size) {
Expand Down Expand Up @@ -771,16 +772,12 @@ bool MMKV::setDataForKey(MMBuffer &&data, const std::string &key) {
SCOPEDLOCK(m_exclusiveProcessLock);
checkLoadData();

// m_dic[key] = std::move(data);
auto itr = m_dic.find(key);
if (itr == m_dic.end()) {
itr = m_dic.emplace(key, std::move(data)).first;
} else {
itr->second = std::move(data);
auto ret = appendDataWithKey(data, key);
if (ret) {
m_dic[key] = std::move(data);
m_hasFullWriteback = false;
}
m_hasFullWriteback = false;

return appendDataWithKey(itr->second, key);
return ret;
}

bool MMKV::removeDataForKey(const std::string &key) {
Expand All @@ -798,47 +795,46 @@ bool MMKV::removeDataForKey(const std::string &key) {
return false;
}

constexpr uint32_t ItemSizeHolder = 0x00ffffff, ItemSizeHolderSize = 4;

bool MMKV::appendDataWithKey(const MMBuffer &data, const std::string &key) {
size_t keyLength = key.length();
// size needed to encode the key
size_t size = keyLength + pbRawVarint32Size((int32_t) keyLength);
// size needed to encode the value
size += data.length() + pbRawVarint32Size((int32_t) data.length());

bool isFirstWrite = false;
if (m_actualSize == 0) {
isFirstWrite = true;
size += ItemSizeHolderSize; // size needed to encode the ItemSizeHolder
}

SCOPEDLOCK(m_exclusiveProcessLock);

bool hasEnoughSize = ensureMemorySize(size);

if (!hasEnoughSize || !isFileValid()) {
return false;
}
if (m_actualSize == 0) {
auto allData = MiniPBCoder::encodeDataWithObject(m_dic);
if (allData.length() > 0) {
if (m_crypter) {
m_crypter->reset();
auto ptr = (unsigned char *) allData.getPtr();
m_crypter->encrypt(ptr, ptr, allData.length());
}
writeAcutalSize(allData.length());
m_output->writeRawData(allData); // note: don't write size of data
recaculateCRCDigest();
return true;
}
return false;
} else {
writeAcutalSize(m_actualSize + size);
m_output->writeString(key);
m_output->writeData(data); // note: write size of data
// write holder of size of m_dic
// which will be ignore while decoding
// yet it's required for decoding
if (isFirstWrite) {
m_output->writeInt32(ItemSizeHolder);
}

auto ptr = (uint8_t *) m_ptr + Fixed32Size + m_actualSize - size;
if (m_crypter) {
m_crypter->encrypt(ptr, ptr, size);
}
updateCRCDigest(ptr, size, KeepSequence);
writeAcutalSize(m_actualSize + size);
m_output->writeString(key);
m_output->writeData(data); // note: write size of data

return true;
auto ptr = (uint8_t *) m_ptr + Fixed32Size + m_actualSize - size;
if (m_crypter) {
m_crypter->encrypt(ptr, ptr, size);
}
updateCRCDigest(ptr, size, KeepSequence);

return true;
}

bool MMKV::fullWriteback() {
Expand Down
2 changes: 1 addition & 1 deletion Android/MMKV/mmkv/src/main/cpp/MMKVLog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void _MMKVLogWithLevel(
}

if (g_isLogRedirecting) {
mmkvLog((int) level, file, line, func, message);
mmkv::mmkvLog((int) level, file, line, func, message);
} else {
__android_log_print(MMKVLogLevelDesc(level), APPNAME, "<%s:%d::%s> %s", file, line,
func, message.c_str());
Expand Down
Loading

0 comments on commit a4f7f49

Please sign in to comment.