historically Android mistakenly use mmapKey as mmapID, we try migrate back to normal when possible
| 183 | |
| 184 | // historically Android mistakenly use mmapKey as mmapID, we try migrate back to normal when possible |
| 185 | MigrateStatus tryMigrateLegacyMMKVFile(const string &mmapID, const string *rootPath, bool alreadyAbsolute) { |
| 186 | auto legacyID = legacyMmapedKVKey(mmapID, rootPath); |
| 187 | if (legacyID == mmapID) { |
| 188 | // it's not specially encoded |
| 189 | return MigrateStatus::NotSpecial; |
| 190 | } |
| 191 | auto path = mappedKVPathWithID(legacyID, rootPath, MMKV_MULTI_PROCESS, alreadyAbsolute); |
| 192 | auto targetPath = mappedKVPathWithID(mmapID, rootPath, MMKV_MULTI_PROCESS, alreadyAbsolute); |
| 193 | bool oldExit = isFileExist(path); |
| 194 | bool newExist = isFileExist(targetPath); |
| 195 | if (oldExit) { |
| 196 | if (newExist) { |
| 197 | MMKVWarning("both legacy file [%s] modify: %lld ms, and new file [%s] modify: %lld ms exist", |
| 198 | path.c_str(), getFileModifyTimeInMS(path.c_str()), |
| 199 | targetPath.c_str(), getFileModifyTimeInMS(targetPath.c_str())); |
| 200 | return MigrateStatus::OldAndNewExist; |
| 201 | } |
| 202 | auto file = File(path, OpenFlag::ReadWrite); |
| 203 | if (file.isFileValid()) { |
| 204 | // check if it's opened by other process |
| 205 | auto fileMigrationLock = FileLock(file.getFd(), true, false, 2, 3); |
| 206 | auto exclusiveMigrationLock = InterProcessLock(&fileMigrationLock, ExclusiveLockType); |
| 207 | // works even if it's opened by us |
| 208 | if (exclusiveMigrationLock.try_lock()) { |
| 209 | if (tryAtomicRename(path, targetPath)) { |
| 210 | if (tryAtomicRename(crcPathWithPath(path), crcPathWithPath(targetPath))) { |
| 211 | MMKVInfo("Migrated legacy MMKV [%s] to [%s] in path %s", legacyID.c_str(), mmapID.c_str(), rootPath->c_str()); |
| 212 | return MigrateStatus::OldToNewMigrated; |
| 213 | } |
| 214 | } |
| 215 | } else { |
| 216 | MMKVInfo("Can't migrate legacy MMKV [%s] to [%s] in path %s, try next time.", legacyID.c_str(), mmapID.c_str(), rootPath->c_str()); |
| 217 | } |
| 218 | } |
| 219 | return MigrateStatus::OldToNewMigrateFail; |
| 220 | } |
| 221 | return newExist ? MigrateStatus::NewExist : MigrateStatus::NoneExist; |
| 222 | } |
| 223 | |
| 224 | MMKV *MMKV::getMMKVWithID(const string &mmapID, const MMKVConfig &config) { |
| 225 | if (mmapID.empty() || !g_instanceLock) { |
no test coverage detected