Skip to content

posix_tutorial

guoling edited this page Apr 19, 2024 · 8 revisions

MMKV for POSIX

MMKV is an efficient, small, easy-to-use mobile key-value storage framework used in the WeChat application. It's currently available on both Android, iOS/macOS, Windows and POSIX.

Tutorial

You can use MMKV as you go. All changes are saved immediately, no save, no sync calls are needed.

Configuration

  • Setup MMKV on App startup, say in your main(), add these codes:

    #include "MMKV.h"
    
    int main() {
        std::string rootDir = getYourAppDocumentDir();
        MMKV::initializeMMKV(rootDir);
        //...
    }

CRUD Operations

  • MMKV has a global instance, that can be used directly:

    auto mmkv = MMKV::defaultMMKV();
    
    mmkv->set(true, "bool");
    std::cout << "bool = " << mmkv->getBool("bool") << std::endl;
    
    mmkv->set(1024, "int32");
    std::cout << "int32 = " << mmkv->getInt32("int32") << std::endl;
    
    mmkv->set(numeric_limits<uint32_t>::max(), "uint32");
    std::cout << "uint32 = " << mmkv->getUInt32("uint32") << std::endl;
    
    mmkv->set(numeric_limits<int64_t>::min(), "int64");
    std::cout << "int64 = " << mmkv->getInt64("int64") << std::endl;
    
    mmkv->set(numeric_limits<uint64_t>::max(), "uint64");
    std::cout << "uint64 = " << mmkv->getUInt64("uint64") << std::endl;
    
    mmkv->set(3.14f, "float");
    std::cout << "float = " << mmkv->getFloat("float") << std::endl;
    
    mmkv->set(numeric_limits<double>::max(), "double");
    std::cout << "double = " << mmkv->getDouble("double") << std::endl;
    
    mmkv->set("Hello, MMKV for Windows", "string");
    std::string result;
    if (mmkv->getString("string", result)) {
       std::cout << "string = " << result << std::endl;
    }

    As you can see, MMKV is quite easy to use.

  • Deleting & Querying:

    auto kv = MMKV::defaultMMKV();
         
    mmkv->removeValueForKey("bool");
    std::cout << "bool = " << mmkv->getBool("bool") << std::endl;
    
    mmkv->removeValuesForKeys({"int32", "int64"});
    std::cout << "allKeys: ";
    for (auto &key : mmkv->allKeys()) {
        std::cout << key << ", ";
    }
    std::cout << std::endl;
          
    bool hasBool = mmkv->containsKey("bool");
  • If different modules/logics need isolated storage, you can also create your own MMKV instance separately:

    auto mmkv = MMKV::mmkvWithID("MyID");
    mmkv->set(true, "bool");
  • If multi-process accessing is needed, you can set MMKV_MULTI_PROCESS on MMKV initialization:

    auto mmkv = MMKV::mmkvWithID("InterProcessKV", MMKV_MULTI_PROCESS);
    mmkv->set(true, "bool");

Supported Types

  • Primitive Types:

    • bool, int32, int64, uint32, uint64, float, double
  • Classes & Collections:

    • std::string, std::vector<std::string>, mmkv::MMBuffer

Logs

  • By default, MMKV prints log to stdout, which is not convenient for diagnosing online issues. You can set up MMKV log redirecting on App startup. Implement callback function with type mmkv::LogHandler(), add some code like these:

    void MyLogHandler(MMKVLogLevel level, const char *file, int line, const char *function, const string &message) {
        auto desc = [level] {
            switch (level) {
                case MMKVLogDebug:
                    return "D";
                case MMKVLogInfo:
                    return "I";
                case MMKVLogWarning:
                    return "W";
                case MMKVLogError:
                    return "E";
                default:
                    return "N";
            }
        }();
        printf("[%s] <%s:%d::%s> %s\n", desc, file, line, function, message.c_str());
    }
    int main() {
        std::string rootDir = getYourAppDocumentDir();
        MMKV::initializeMMKV(rootDir, MMKVLogInfo, MyLogHandler);
        //...
    }

    As for a logging tool, we recommend using xlog, which also comes from the WeChat team.

  • You can turn off MMKV's logging once and for all (which we strongly disrecommend).
    You should never turn MMKV's log off unless you have very strong evidence that it makes your App slow.

    int main() {
        std::string rootDir = getYourAppDocumentDir();
        MMKV::initializeMMKV(rootDir, MMKVLogNone);
        //...
    }

Backup & Restore

  • You can use MMKV's backup & restore API to backup your data to somewhere else, and restore them later.

    std::string rootDir = "/tmp/mmkv_backup";
    auto ret = MMKV::backupOneToDirectory(mmapID, rootDir);
    // backup one instance
    var ret = MMKV.backupOneToDirectory(mmapID, backupRootDir);
    // backup all instances
    auto count = MMKV::backupAllToDirectory(rootDir);
    
    // restore one instance
    ret = MMKV::restoreOneFromDirectory(mmapID, rootDir);
    // restore all instances
    count = MMKV::restoreAllFromDirectory(rootDir);

Auto Expiration

  • Starting from v1.3.0, you can upgrade MMKV to auto key expiration. Note that this is a breaking change. Once upgraded to auto key expiration, the file is not valid for any older version of MMKV (<= v1.2.16) to operate correctly.

  • Global Expiration. The most simple way to do it is to turn on auto key expiration for all keys in the whole file.

    // expire in a day
    mmkv->enableAutoKeyExpire(24 * 60 * 60);

    Or, if you prefer, you can enable auto key expiration without setting a global expiration duration. In this case, each key is not expired by default.

    // enable auto key expiration without global duration
    mmkv->enableAutoKeyExpire(MMKV::ExpireNever); // MMKV::ExpireNever = 0
  • Individual Expiration. You can set a special expiration duration for a key, regardless with the file has a global duration or not. Note that you have to enable auto key expiration first.

    // enable auto key expiration with an hour duration
    mmkv->enableAutoKeyExpire(60 * 60);
    
    // set a key with the file's global expiration duration, aka 60 * 60
    mmkv->set("some value", "key_1");
    
    // set a special key that expires in two hours
    mmkv->set("some value", "key_2", 2 * 60 * 60);
    
    // set a special key that never expires
    mmkv->set("some value", "key_3", MMKV::ExpireNever);

    Or, if you prefer, you can enable auto key expiration without setting a global expiration duration. In this case, each key is not expired by default.

    // enable auto key expiration without global duration
    mmkv->enableAutoKeyExpire(MMKV::ExpireNever); // MMKV::ExpireNever = 0
    
    // set a key that never expires
    mmkv->set("some value", "key_1");
    
    // set a special key that expires in an hour
    mmkv->set("some value", "key_2", 60 * 60);
  • The expire duration is counted in seconds. You can use any other duration you prefer. For example, expiration in a week is 7 * 24 * 60 * 60.

Next

Clone this wiki locally