or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-management.mddata-storage.mdencryption.mdindex.mdinitialization.mdinstance-management.mdmulti-process.mdnamespace.md

data-management.mddocs/

0

# Data Management

1

2

Advanced data management operations including key inspection, file operations, backup/restore capabilities, and performance optimization methods.

3

4

## Capabilities

5

6

### Key Inspection

7

8

Methods for inspecting and analyzing stored keys and their properties.

9

10

```java { .api }

11

/**

12

* Check whether MMKV contains the key.

13

* @param key The key to check

14

* @return True if key exists, false otherwise

15

*/

16

public boolean containsKey(String key);

17

18

/**

19

* Get all keys in the MMKV instance.

20

* @return Array of all keys, or null if no keys exist

21

*/

22

public String[] allKeys();

23

24

/**

25

* Get all non-expired keys in the MMKV instance.

26

* Note: This call has performance costs.

27

* @return Array of non-expired keys, or null if no keys exist

28

*/

29

public String[] allNonExpireKeys();

30

31

/**

32

* Get the total count of all keys.

33

* @return The total number of keys

34

*/

35

public long count();

36

37

/**

38

* Get the total count of all non-expired keys.

39

* Note: This call has performance costs.

40

* @return The total number of non-expired keys

41

*/

42

public long countNonExpiredKeys();

43

```

44

45

**Usage Example:**

46

47

```java

48

MMKV kv = MMKV.defaultMMKV();

49

50

// Add some test data

51

kv.encode("user_id", 123);

52

kv.encode("username", "john_doe");

53

kv.encode("is_premium", true);

54

kv.encode("temp_data", "temporary", MMKV.ExpireInMinute);

55

56

// Check if specific keys exist

57

boolean hasUserId = kv.containsKey("user_id"); // true

58

boolean hasEmail = kv.containsKey("email"); // false

59

60

// Get all keys

61

String[] allKeys = kv.allKeys();

62

if (allKeys != null) {

63

Log.d("MMKV", "Total keys: " + allKeys.length);

64

for (String key : allKeys) {

65

Log.d("MMKV", "Key: " + key);

66

}

67

}

68

69

// Get count of keys

70

long totalCount = kv.count(); // 4

71

long nonExpiredCount = kv.countNonExpiredKeys(); // 3 (after temp_data expires)

72

73

Log.d("MMKV", String.format("Total: %d, Non-expired: %d", totalCount, nonExpiredCount));

74

75

// Get only non-expired keys (more expensive operation)

76

String[] activeKeys = kv.allNonExpireKeys();

77

```

78

79

### Value Size Analysis

80

81

Analyze the size and memory usage of stored values.

82

83

```java { .api }

84

/**

85

* Get the actual size consumption of the key's value.

86

* Note: Might be slightly larger than value's length due to metadata.

87

* @param key The key of the value

88

* @return The size in bytes

89

*/

90

public int getValueSize(String key);

91

92

/**

93

* Get the actual size of the key's value.

94

* Returns string length or byte array length, etc.

95

* @param key The key of the value

96

* @return The actual value size in bytes

97

*/

98

public int getValueActualSize(String key);

99

100

/**

101

* Get the size of the underlying file.

102

* Aligned to disk block size, typically 4K for Android devices.

103

* @return The total file size in bytes

104

*/

105

public long totalSize();

106

107

/**

108

* Get the actual used size of the MMKV instance.

109

* This size might increase and decrease as MMKV does insertion and full write back.

110

* @return The actual used size in bytes

111

*/

112

public long actualSize();

113

```

114

115

**Usage Example:**

116

117

```java

118

MMKV kv = MMKV.defaultMMKV();

119

120

// Store different types of data

121

kv.encode("short_string", "Hello");

122

kv.encode("long_string", "This is a much longer string that will take more space");

123

kv.encode("large_number", 1234567890L);

124

byte[] imageData = new byte[1024 * 100]; // 100KB of data

125

kv.encode("image_data", imageData);

126

127

// Analyze individual value sizes

128

int shortStringSize = kv.getValueSize("short_string"); // ~5 + metadata

129

int shortStringActual = kv.getValueActualSize("short_string"); // 5

130

int longStringSize = kv.getValueSize("long_string");

131

int imageDataSize = kv.getValueSize("image_data"); // ~100KB + metadata

132

133

Log.d("MMKV", String.format("Short string: %d bytes (actual: %d)",

134

shortStringSize, shortStringActual));

135

Log.d("MMKV", String.format("Long string: %d bytes", longStringSize));

136

Log.d("MMKV", String.format("Image data: %d bytes", imageDataSize));

137

138

// Analyze overall file sizes

139

long totalFileSize = kv.totalSize(); // File size on disk (aligned to 4K blocks)

140

long actualUsedSize = kv.actualSize(); // Actual data size used

141

142

Log.d("MMKV", String.format("Total file size: %d bytes (%.2f KB)",

143

totalFileSize, totalFileSize / 1024.0));

144

Log.d("MMKV", String.format("Actual used size: %d bytes (%.2f KB)",

145

actualUsedSize, actualUsedSize / 1024.0));

146

Log.d("MMKV", String.format("Efficiency: %.1f%%",

147

(actualUsedSize * 100.0) / totalFileSize));

148

```

149

150

### Data Removal

151

152

Remove individual keys, multiple keys, or clear all data.

153

154

```java { .api }

155

/**

156

* Remove the value for a specific key.

157

* @param key The key to remove

158

*/

159

public void removeValueForKey(String key);

160

161

/**

162

* Batch remove multiple keys from the MMKV instance.

163

* @param arrKeys Array of keys to be removed

164

*/

165

public void removeValuesForKeys(String[] arrKeys);

166

167

/**

168

* Clear all key-values inside the MMKV instance.

169

* The data file will be trimmed down to pageSize and sync operations called.

170

* For better performance without file trimming, use clearAllWithKeepingSpace().

171

*/

172

public void clearAll();

173

174

/**

175

* Faster clearAll() implementation that keeps the file size.

176

* The file size is kept as previous for later use.

177

*/

178

public void clearAllWithKeepingSpace();

179

```

180

181

**Usage Example:**

182

183

```java

184

MMKV kv = MMKV.defaultMMKV();

185

186

// Add test data

187

kv.encode("keep_this", "important data");

188

kv.encode("temp1", "temporary data 1");

189

kv.encode("temp2", "temporary data 2");

190

kv.encode("temp3", "temporary data 3");

191

kv.encode("delete_this", "data to delete");

192

193

// Remove single key

194

kv.removeValueForKey("delete_this");

195

196

// Remove multiple keys at once (more efficient than individual removes)

197

String[] keysToRemove = {"temp1", "temp2", "temp3"};

198

kv.removeValuesForKeys(keysToRemove);

199

200

// Check what's left

201

String[] remainingKeys = kv.allKeys();

202

Log.d("MMKV", "Remaining keys: " + Arrays.toString(remainingKeys)); // Should show "keep_this"

203

204

// Clear all data (with file trimming for space reclamation)

205

long sizeBefore = kv.totalSize();

206

kv.clearAll();

207

long sizeAfter = kv.totalSize();

208

Log.d("MMKV", String.format("Size before clear: %d, after: %d", sizeBefore, sizeAfter));

209

210

// Alternative: clear all but keep file size for performance

211

kv.encode("test", "data");

212

kv.clearAllWithKeepingSpace(); // Faster, but doesn't reclaim disk space

213

```

214

215

### File Maintenance

216

217

Operations for maintaining and optimizing MMKV file storage.

218

219

```java { .api }

220

/**

221

* Reduce file size after lots of deletions.

222

* The totalSize() of an MMKV instance won't reduce after deleting key-values.

223

* Call this method after lots of deleting if you care about disk usage.

224

* Note: clearAll() has a similar effect.

225

*/

226

public void trim();

227

228

/**

229

* Save all mmap memory to file synchronously.

230

* You don't need to call this normally - MMKV handles persistence automatically.

231

* Use only if you worry about device running out of battery.

232

*/

233

public void sync();

234

235

/**

236

* Save all mmap memory to file asynchronously.

237

* No need to call this unless you worry about losing battery power.

238

*/

239

public void async();

240

241

/**

242

* Clear memory cache of the MMKV instance.

243

* Call this on memory warning to free up RAM.

244

* Any subsequent call will trigger key-values loading from file again.

245

*/

246

public void clearMemoryCache();

247

248

/**

249

* Call this method if the MMKV instance is no longer needed.

250

* Any subsequent call to MMKV instances with the same ID is undefined behavior.

251

*/

252

public void close();

253

```

254

255

**Usage Example:**

256

257

```java

258

public class MMKVMaintenanceExample {

259

260

private MMKV kv;

261

262

public void demonstrateFileMaintenance() {

263

kv = MMKV.mmkvWithID("maintenance_example");

264

265

// Add lots of data

266

for (int i = 0; i < 10000; i++) {

267

kv.encode("key_" + i, "value_" + i);

268

}

269

270

long sizeBefore = kv.totalSize();

271

Log.d("MMKV", "Size before deletions: " + sizeBefore);

272

273

// Delete most of the data

274

for (int i = 0; i < 9000; i++) {

275

kv.removeValueForKey("key_" + i);

276

}

277

278

long sizeAfterDeletion = kv.totalSize();

279

Log.d("MMKV", "Size after deletions: " + sizeAfterDeletion); // Still large

280

281

// Trim file to reclaim space

282

kv.trim();

283

284

long sizeAfterTrim = kv.totalSize();

285

Log.d("MMKV", "Size after trim: " + sizeAfterTrim); // Much smaller

286

287

// Force synchronous save to disk

288

kv.sync();

289

290

// Or use asynchronous save for better performance

291

kv.async();

292

}

293

294

public void handleMemoryPressure() {

295

// Clear memory cache to free RAM

296

kv.clearMemoryCache();

297

Log.d("MMKV", "Memory cache cleared due to memory pressure");

298

}

299

300

@Override

301

protected void onDestroy() {

302

super.onDestroy();

303

// Close MMKV instance when no longer needed

304

if (kv != null) {

305

kv.close();

306

kv = null;

307

}

308

}

309

}

310

```

311

312

### Data Import and Export

313

314

Import data from other sources and export for backup purposes.

315

316

```java { .api }

317

/**

318

* Import all key-value items from another MMKV instance.

319

* @param src The source MMKV instance to import from

320

* @return Count of items imported

321

*/

322

public long importFrom(MMKV src);

323

324

/**

325

* Atomically migrate all key-values from an existing SharedPreferences.

326

* @param preferences The SharedPreferences to import from

327

* @return The total count of key-values imported

328

*/

329

public int importFromSharedPreferences(SharedPreferences preferences);

330

```

331

332

**Usage Example:**

333

334

```java

335

public class MMKVImportExportExample {

336

337

/**

338

* Migrate from SharedPreferences to MMKV.

339

*/

340

public void migrateFromSharedPreferences(Context context) {

341

// Get existing SharedPreferences

342

SharedPreferences oldPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE);

343

344

// Create new MMKV instance

345

MMKV newKv = MMKV.mmkvWithID("user_prefs");

346

347

// Import all data from SharedPreferences

348

int importedCount = newKv.importFromSharedPreferences(oldPrefs);

349

350

Log.d("MMKV", "Imported " + importedCount + " items from SharedPreferences");

351

352

// Verify the migration

353

if (importedCount > 0) {

354

// Clear old SharedPreferences after successful migration

355

oldPrefs.edit().clear().apply();

356

Log.d("MMKV", "Successfully migrated to MMKV");

357

}

358

}

359

360

/**

361

* Copy data between MMKV instances.

362

*/

363

public void copyDataBetweenInstances() {

364

// Source instance with data

365

MMKV sourceKv = MMKV.mmkvWithID("source_data");

366

sourceKv.encode("user_id", 123);

367

sourceKv.encode("username", "john");

368

sourceKv.encode("settings", "dark_mode=true");

369

370

// Destination instance

371

MMKV destKv = MMKV.mmkvWithID("backup_data");

372

373

// Import all data from source to destination

374

long importedCount = destKv.importFrom(sourceKv);

375

376

Log.d("MMKV", "Imported " + importedCount + " items to backup");

377

378

// Verify the copy

379

String username = destKv.decodeString("username"); // "john"

380

int userId = destKv.decodeInt("user_id"); // 123

381

382

Log.d("MMKV", String.format("Verified backup: user=%s, id=%d", username, userId));

383

}

384

385

/**

386

* Create incremental backup.

387

*/

388

public void createIncrementalBackup() {

389

MMKV mainKv = MMKV.defaultMMKV();

390

MMKV backupKv = MMKV.mmkvWithID("incremental_backup");

391

392

// Get timestamp of last backup

393

long lastBackupTime = backupKv.decodeLong("last_backup_time", 0);

394

395

// Import all current data (MMKV handles duplicates efficiently)

396

long importedCount = backupKv.importFrom(mainKv);

397

398

// Update backup timestamp

399

backupKv.encode("last_backup_time", System.currentTimeMillis());

400

401

Log.d("MMKV", String.format("Incremental backup: %d items, last backup: %d",

402

importedCount, lastBackupTime));

403

}

404

}

405

```

406

407

### Backup and Restore Operations

408

409

File-level backup and restore operations for data protection.

410

411

```java { .api }

412

/**

413

* Backup one MMKV instance to destination directory.

414

* @param mmapID The MMKV ID to backup

415

* @param dstDir The backup destination directory

416

* @param rootPath The customize root path of the MMKV, null for default root

417

* @return True if backup successful

418

*/

419

public static boolean backupOneToDirectory(String mmapID, String dstDir, String rootPath);

420

421

/**

422

* Restore one MMKV instance from source directory.

423

* @param mmapID The MMKV ID to restore

424

* @param srcDir The restore source directory

425

* @param rootPath The customize root path of the MMKV, null for default root

426

* @return True if restore successful

427

*/

428

public static boolean restoreOneMMKVFromDirectory(String mmapID, String srcDir, String rootPath);

429

430

/**

431

* Backup all MMKV instances from default root dir to destination directory.

432

* @param dstDir The backup destination directory

433

* @return Count of MMKV instances successfully backed up

434

*/

435

public static long backupAllToDirectory(String dstDir);

436

437

/**

438

* Restore all MMKV instances from source directory to default root dir.

439

* @param srcDir The restore source directory

440

* @return Count of MMKV instances successfully restored

441

*/

442

public static long restoreAllFromDirectory(String srcDir);

443

```

444

445

**Usage Example:**

446

447

```java

448

public class MMKVBackupRestoreExample {

449

450

/**

451

* Create backup of specific MMKV instances.

452

*/

453

public void backupSpecificInstances(Context context) {

454

// Create backup directory

455

File backupDir = new File(context.getExternalFilesDir(null), "mmkv_backup");

456

if (!backupDir.exists()) {

457

backupDir.mkdirs();

458

}

459

460

String backupPath = backupDir.getAbsolutePath();

461

462

// Backup specific instances

463

boolean userBackup = MMKV.backupOneToDirectory("user_data", backupPath, null);

464

boolean settingsBackup = MMKV.backupOneToDirectory("app_settings", backupPath, null);

465

466

Log.d("MMKV", String.format("Backup results - User: %b, Settings: %b",

467

userBackup, settingsBackup));

468

469

if (userBackup && settingsBackup) {

470

// Store backup metadata

471

MMKV backupMeta = MMKV.mmkvWithID("backup_metadata");

472

backupMeta.encode("last_backup_time", System.currentTimeMillis());

473

backupMeta.encode("backup_path", backupPath);

474

backupMeta.encode("backup_count", 2);

475

}

476

}

477

478

/**

479

* Backup all MMKV instances.

480

*/

481

public void backupAllInstances(Context context) {

482

File backupDir = new File(context.getExternalFilesDir(null), "mmkv_full_backup");

483

backupDir.mkdirs();

484

485

// Backup all instances

486

long backedUpCount = MMKV.backupAllToDirectory(backupDir.getAbsolutePath());

487

488

Log.d("MMKV", "Backed up " + backedUpCount + " MMKV instances");

489

490

// Create backup manifest

491

MMKV manifest = MMKV.mmkvWithID("backup_manifest");

492

manifest.encode("backup_timestamp", System.currentTimeMillis());

493

manifest.encode("backup_count", backedUpCount);

494

manifest.encode("backup_type", "full");

495

}

496

497

/**

498

* Restore from backup.

499

*/

500

public void restoreFromBackup(String backupPath) {

501

try {

502

// Restore specific instances

503

boolean userRestored = MMKV.restoreOneMMKVFromDirectory("user_data", backupPath, null);

504

boolean settingsRestored = MMKV.restoreOneMMKVFromDirectory("app_settings", backupPath, null);

505

506

if (userRestored && settingsRestored) {

507

Log.d("MMKV", "Successfully restored specific instances");

508

}

509

510

// Or restore all instances

511

long restoredCount = MMKV.restoreAllFromDirectory(backupPath);

512

Log.d("MMKV", "Restored " + restoredCount + " instances from backup");

513

514

} catch (Exception e) {

515

Log.e("MMKV", "Failed to restore from backup", e);

516

}

517

}

518

519

/**

520

* Automated backup with rotation.

521

*/

522

public void automatedBackupWithRotation(Context context) {

523

File backupRoot = new File(context.getExternalFilesDir(null), "mmkv_backups");

524

backupRoot.mkdirs();

525

526

// Create timestamped backup directory

527

String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)

528

.format(new Date());

529

File currentBackup = new File(backupRoot, "backup_" + timestamp);

530

currentBackup.mkdirs();

531

532

// Perform backup

533

long backedUpCount = MMKV.backupAllToDirectory(currentBackup.getAbsolutePath());

534

535

if (backedUpCount > 0) {

536

// Keep only last 5 backups

537

File[] backups = backupRoot.listFiles((dir, name) -> name.startsWith("backup_"));

538

if (backups != null && backups.length > 5) {

539

Arrays.sort(backups, (a, b) -> a.getName().compareTo(b.getName()));

540

541

// Delete oldest backups

542

for (int i = 0; i < backups.length - 5; i++) {

543

deleteRecursive(backups[i]);

544

Log.d("MMKV", "Deleted old backup: " + backups[i].getName());

545

}

546

}

547

548

Log.d("MMKV", String.format("Automated backup completed: %d instances, %s",

549

backedUpCount, timestamp));

550

}

551

}

552

553

private void deleteRecursive(File file) {

554

if (file.isDirectory()) {

555

File[] children = file.listFiles();

556

if (children != null) {

557

for (File child : children) {

558

deleteRecursive(child);

559

}

560

}

561

}

562

file.delete();

563

}

564

}

565

```

566

567

### Storage Management

568

569

Methods for managing MMKV storage files and checking storage status.

570

571

```java { .api }

572

/**

573

* Remove the storage of the MMKV, including data file and meta file (.crc).

574

* Note: The existing instance (if any) will be closed and destroyed.

575

* @param mmapID The unique ID of the MMKV instance

576

* @return True if removal successful

577

*/

578

public static boolean removeStorage(String mmapID);

579

580

/**

581

* Remove MMKV storage with custom root path.

582

* @param mmapID The unique ID of the MMKV instance

583

* @param rootPath The folder of the MMKV instance, null for default

584

* @return True if removal successful

585

*/

586

public static boolean removeStorage(String mmapID, String rootPath);

587

588

/**

589

* Check existence of the MMKV file.

590

* @param mmapID The unique ID of the MMKV instance

591

* @return True if file exists

592

*/

593

public static boolean checkExist(String mmapID);

594

595

/**

596

* Check existence of MMKV file with custom root path.

597

* @param mmapID The unique ID of the MMKV instance

598

* @param rootPath The folder of the MMKV instance, null for default

599

* @return True if file exists

600

*/

601

public static boolean checkExist(String mmapID, String rootPath);

602

603

/**

604

* Check whether the MMKV file is valid.

605

* Note: Don't use this to check existence - result is undefined on nonexistent files.

606

* @param mmapID The unique ID of the MMKV instance

607

* @return True if file is valid

608

*/

609

public static boolean isFileValid(String mmapID);

610

611

/**

612

* Check MMKV file validity with custom root path.

613

* @param mmapID The unique ID of the MMKV instance

614

* @param rootPath The folder of the MMKV instance, null for default

615

* @return True if file is valid

616

*/

617

public static boolean isFileValid(String mmapID, String rootPath);

618

```

619

620

**Usage Example:**

621

622

```java

623

public class MMKVStorageManagementExample {

624

625

/**

626

* Clean up unused MMKV instances.

627

*/

628

public void cleanupUnusedInstances() {

629

String[] instancesToCheck = {"temp_cache", "old_user_data", "deprecated_settings"};

630

631

for (String instanceId : instancesToCheck) {

632

if (MMKV.checkExist(instanceId)) {

633

if (MMKV.isFileValid(instanceId)) {

634

// File exists and is valid - check if still needed

635

if (isInstanceStillNeeded(instanceId)) {

636

Log.d("MMKV", "Keeping instance: " + instanceId);

637

} else {

638

// Remove unused instance

639

boolean removed = MMKV.removeStorage(instanceId);

640

Log.d("MMKV", "Removed unused instance " + instanceId + ": " + removed);

641

}

642

} else {

643

Log.w("MMKV", "Invalid file detected: " + instanceId);

644

// Remove corrupted file

645

MMKV.removeStorage(instanceId);

646

}

647

} else {

648

Log.d("MMKV", "Instance doesn't exist: " + instanceId);

649

}

650

}

651

}

652

653

/**

654

* Health check for all MMKV instances.

655

*/

656

public void performHealthCheck() {

657

// Get all MMKV files in default directory

658

File mmkvRoot = new File(MMKV.getRootDir());

659

File[] mmkvFiles = mmkvRoot.listFiles((dir, name) -> !name.endsWith(".crc"));

660

661

if (mmkvFiles != null) {

662

for (File file : mmkvFiles) {

663

String instanceId = file.getName();

664

665

boolean exists = MMKV.checkExist(instanceId);

666

boolean valid = exists && MMKV.isFileValid(instanceId);

667

668

Log.d("MMKV", String.format("Health check - %s: exists=%b, valid=%b",

669

instanceId, exists, valid));

670

671

if (exists && !valid) {

672

Log.e("MMKV", "Corrupted MMKV file detected: " + instanceId);

673

// Handle corruption - backup and recreate, or remove

674

handleCorruptedFile(instanceId);

675

}

676

}

677

}

678

}

679

680

/**

681

* Get storage statistics.

682

*/

683

public void getStorageStats() {

684

File mmkvRoot = new File(MMKV.getRootDir());

685

long totalSize = 0;

686

int fileCount = 0;

687

688

File[] files = mmkvRoot.listFiles();

689

if (files != null) {

690

for (File file : files) {

691

if (file.isFile()) {

692

totalSize += file.length();

693

fileCount++;

694

}

695

}

696

}

697

698

Log.d("MMKV", String.format("Storage stats - Files: %d, Total size: %d bytes (%.2f KB)",

699

fileCount, totalSize, totalSize / 1024.0));

700

701

// Also check individual instance sizes

702

String[] activeInstances = {"user_data", "app_settings", "cache"};

703

for (String instanceId : activeInstances) {

704

if (MMKV.checkExist(instanceId)) {

705

MMKV kv = MMKV.mmkvWithID(instanceId);

706

long instanceSize = kv.totalSize();

707

long actualSize = kv.actualSize();

708

709

Log.d("MMKV", String.format("%s - Total: %d bytes, Used: %d bytes (%.1f%%)",

710

instanceId, instanceSize, actualSize,

711

(actualSize * 100.0) / instanceSize));

712

}

713

}

714

}

715

716

private boolean isInstanceStillNeeded(String instanceId) {

717

// Implement your logic to determine if instance is still needed

718

// For example, check app settings, user preferences, etc.

719

return !instanceId.startsWith("temp_");

720

}

721

722

private void handleCorruptedFile(String instanceId) {

723

Log.w("MMKV", "Handling corrupted file: " + instanceId);

724

725

// Try to backup what we can

726

try {

727

File backupDir = new File(MMKV.getRootDir(), "corrupted_backup");

728

backupDir.mkdirs();

729

MMKV.backupOneToDirectory(instanceId, backupDir.getAbsolutePath(), null);

730

} catch (Exception e) {

731

Log.e("MMKV", "Failed to backup corrupted file", e);

732

}

733

734

// Remove corrupted file

735

MMKV.removeStorage(instanceId);

736

737

// Optionally recreate with default values

738

// recreateWithDefaults(instanceId);

739

}

740

}

741

```