react-native-mmkv 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -237,12 +237,12 @@
237
237
  CB9563F123AB2E9100ACCD39 /* MiniPBCoder.h */,
238
238
  CB9563F823AB2E9100ACCD39 /* MMBuffer.cpp */,
239
239
  CB9563FA23AB2E9100ACCD39 /* MMBuffer.h */,
240
- CBD723BE23B5C22800D3CDAF /* MMKV_OSX.cpp */,
241
- CB467F862431D3ED00FD7421 /* MMKV_OSX.h */,
240
+ CB9563ED23AB2E9100ACCD39 /* MMKV.h */,
242
241
  CB9563F223AB2E9100ACCD39 /* MMKV.cpp */,
243
- CB7C029924A0F65B008D77E6 /* MMKV_IO.cpp */,
244
242
  CB7C029E24A0FBC2008D77E6 /* MMKV_IO.h */,
245
- CB9563ED23AB2E9100ACCD39 /* MMKV.h */,
243
+ CB7C029924A0F65B008D77E6 /* MMKV_IO.cpp */,
244
+ CB467F862431D3ED00FD7421 /* MMKV_OSX.h */,
245
+ CBD723BE23B5C22800D3CDAF /* MMKV_OSX.cpp */,
246
246
  CB95641123AB2E9100ACCD39 /* MMKVLog.cpp */,
247
247
  CB9563F423AB2E9100ACCD39 /* MMKVLog.h */,
248
248
  CB9563EC23AB2E9100ACCD39 /* MMKVMetaInfo.hpp */,
@@ -349,7 +349,7 @@
349
349
  CB9563D023AB2D9500ACCD39 /* Project object */ = {
350
350
  isa = PBXProject;
351
351
  attributes = {
352
- LastUpgradeCheck = 1330;
352
+ LastUpgradeCheck = 1420;
353
353
  ORGANIZATIONNAME = lingol;
354
354
  TargetAttributes = {
355
355
  CB9563D723AB2D9500ACCD39 = {
@@ -495,11 +495,14 @@
495
495
  GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
496
496
  GCC_WARN_UNUSED_FUNCTION = YES;
497
497
  GCC_WARN_UNUSED_VARIABLE = YES;
498
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
498
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
499
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
499
500
  MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
500
501
  MTL_FAST_MATH = YES;
501
502
  ONLY_ACTIVE_ARCH = YES;
502
503
  SDKROOT = iphoneos;
504
+ TVOS_DEPLOYMENT_TARGET = 13.0;
505
+ WATCHOS_DEPLOYMENT_TARGET = 4.0;
503
506
  };
504
507
  name = Debug;
505
508
  };
@@ -548,11 +551,14 @@
548
551
  GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
549
552
  GCC_WARN_UNUSED_FUNCTION = YES;
550
553
  GCC_WARN_UNUSED_VARIABLE = YES;
551
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
554
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
555
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
552
556
  MTL_ENABLE_DEBUG_INFO = NO;
553
557
  MTL_FAST_MATH = YES;
554
558
  SDKROOT = iphoneos;
559
+ TVOS_DEPLOYMENT_TARGET = 13.0;
555
560
  VALIDATE_PRODUCT = YES;
561
+ WATCHOS_DEPLOYMENT_TARGET = 4.0;
556
562
  };
557
563
  name = Release;
558
564
  };
@@ -564,6 +570,7 @@
564
570
  CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
565
571
  CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
566
572
  CODE_SIGN_STYLE = Automatic;
573
+ DEAD_CODE_STRIPPING = YES;
567
574
  GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
568
575
  GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
569
576
  GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
@@ -571,15 +578,12 @@
571
578
  GCC_WARN_SHADOW = YES;
572
579
  GCC_WARN_SIGN_COMPARE = YES;
573
580
  GCC_WARN_UNUSED_PARAMETER = NO;
574
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
575
- MACOSX_DEPLOYMENT_TARGET = 10.9;
576
581
  OTHER_LDFLAGS = "-ObjC";
577
582
  PRODUCT_NAME = "$(TARGET_NAME)";
578
583
  SDKROOT = "";
579
584
  SKIP_INSTALL = YES;
580
585
  SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos";
581
586
  TARGETED_DEVICE_FAMILY = "1,2,3";
582
- TVOS_DEPLOYMENT_TARGET = 13.0;
583
587
  };
584
588
  name = Debug;
585
589
  };
@@ -591,6 +595,7 @@
591
595
  CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
592
596
  CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
593
597
  CODE_SIGN_STYLE = Automatic;
598
+ DEAD_CODE_STRIPPING = YES;
594
599
  GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1";
595
600
  GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
596
601
  GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
@@ -599,15 +604,12 @@
599
604
  GCC_WARN_SHADOW = YES;
600
605
  GCC_WARN_SIGN_COMPARE = YES;
601
606
  GCC_WARN_UNUSED_PARAMETER = NO;
602
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
603
- MACOSX_DEPLOYMENT_TARGET = 10.9;
604
607
  OTHER_LDFLAGS = "-ObjC";
605
608
  PRODUCT_NAME = "$(TARGET_NAME)";
606
609
  SDKROOT = "";
607
610
  SKIP_INSTALL = YES;
608
611
  SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvsimulator appletvos";
609
612
  TARGETED_DEVICE_FAMILY = "1,2,3";
610
- TVOS_DEPLOYMENT_TARGET = 13.0;
611
613
  };
612
614
  name = Release;
613
615
  };
@@ -626,15 +628,12 @@
626
628
  GCC_WARN_SHADOW = YES;
627
629
  GCC_WARN_SIGN_COMPARE = YES;
628
630
  GCC_WARN_UNUSED_PARAMETER = NO;
629
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
630
- MACOSX_DEPLOYMENT_TARGET = 10.9;
631
631
  OTHER_LDFLAGS = "-ObjC";
632
632
  PRODUCT_NAME = MMKVCore;
633
633
  SDKROOT = watchos;
634
634
  SKIP_INSTALL = YES;
635
635
  SUPPORTED_PLATFORMS = "watchsimulator watchos";
636
636
  TARGETED_DEVICE_FAMILY = 4;
637
- WATCHOS_DEPLOYMENT_TARGET = 2.0;
638
637
  };
639
638
  name = Debug;
640
639
  };
@@ -654,15 +653,12 @@
654
653
  GCC_WARN_SHADOW = YES;
655
654
  GCC_WARN_SIGN_COMPARE = YES;
656
655
  GCC_WARN_UNUSED_PARAMETER = NO;
657
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
658
- MACOSX_DEPLOYMENT_TARGET = 10.9;
659
656
  OTHER_LDFLAGS = "-ObjC";
660
657
  PRODUCT_NAME = MMKVCore;
661
658
  SDKROOT = watchos;
662
659
  SKIP_INSTALL = YES;
663
660
  SUPPORTED_PLATFORMS = "watchsimulator watchos";
664
661
  TARGETED_DEVICE_FAMILY = 4;
665
- WATCHOS_DEPLOYMENT_TARGET = 2.0;
666
662
  };
667
663
  name = Release;
668
664
  };
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "1330"
3
+ LastUpgradeVersion = "1420"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <Scheme
3
- LastUpgradeVersion = "1330"
3
+ LastUpgradeVersion = "1420"
4
4
  version = "1.3">
5
5
  <BuildAction
6
6
  parallelizeBuildables = "YES"
@@ -18,12 +18,15 @@
18
18
  * limitations under the License.
19
19
  */
20
20
 
21
+ #define NOMINMAX // undefine max/min
22
+
21
23
  #include "MMBuffer.h"
22
24
  #include <cerrno>
23
25
  #include <cstdlib>
24
26
  #include <cstring>
25
27
  #include <utility>
26
28
  #include <stdexcept>
29
+ #include <algorithm>
27
30
 
28
31
  #ifdef MMKV_APPLE
29
32
  # if __has_feature(objc_arc)
@@ -107,6 +110,21 @@ MMBuffer::MMBuffer(MMBuffer &&other) noexcept : type(other.type) {
107
110
  }
108
111
  }
109
112
 
113
+ MMBuffer::MMBuffer(MMBuffer &&other, size_t length) noexcept : type(other.type) {
114
+ if (type == MMBufferType_Normal) {
115
+ size = std::min(other.size, length);
116
+ ptr = other.ptr;
117
+ isNoCopy = other.isNoCopy;
118
+ #ifdef MMKV_APPLE
119
+ m_data = other.m_data;
120
+ #endif
121
+ other.detach();
122
+ } else {
123
+ paddedSize = std::min(other.paddedSize, static_cast<uint8_t>(length));
124
+ memcpy(paddedBuffer, other.paddedBuffer, paddedSize);
125
+ }
126
+ }
127
+
110
128
  MMBuffer &MMBuffer::operator=(MMBuffer &&other) noexcept {
111
129
  if (type == MMBufferType_Normal) {
112
130
  if (other.type == MMBufferType_Normal) {
@@ -77,6 +77,7 @@ public:
77
77
  #endif
78
78
 
79
79
  MMBuffer(MMBuffer &&other) noexcept;
80
+ MMBuffer(MMBuffer &&other, size_t length) noexcept;
80
81
  MMBuffer &operator=(MMBuffer &&other) noexcept;
81
82
 
82
83
  ~MMBuffer();
@@ -40,6 +40,7 @@
40
40
  #include <cstring>
41
41
  #include <unordered_set>
42
42
  //#include <unistd.h>
43
+ #include <cassert>
43
44
 
44
45
  #if defined(__aarch64__) && defined(__linux)
45
46
  # include <asm/hwcap.h>
@@ -69,8 +70,6 @@ constexpr auto SPECIAL_CHARACTER_DIRECTORY_NAME = L"specialCharacter";
69
70
  constexpr auto CRC_SUFFIX = L".crc";
70
71
  #endif
71
72
 
72
- constexpr uint32_t Fixed32Size = pbFixed32Size();
73
-
74
73
  MMKV_NAMESPACE_BEGIN
75
74
 
76
75
  static MMKVPath_t encodeFilePath(const string &mmapID, const MMKVPath_t &rootDir);
@@ -307,6 +306,7 @@ void MMKV::clearMemoryCache() {
307
306
  m_output = nullptr;
308
307
 
309
308
  m_file->clearMemoryCache();
309
+ m_metaFile->clearMemoryCache();
310
310
  m_actualSize = 0;
311
311
  m_metaInfo->m_crcDigest = 0;
312
312
  }
@@ -419,121 +419,257 @@ void MMKV::updateCRCDigest(const uint8_t *ptr, size_t length) {
419
419
  // set & get
420
420
 
421
421
  bool MMKV::set(bool value, MMKVKey_t key) {
422
+ return set(value, key, m_expiredInSeconds);
423
+ }
424
+
425
+ bool MMKV::set(bool value, MMKVKey_t key, uint32_t expireDuration) {
422
426
  if (isKeyEmpty(key)) {
423
427
  return false;
424
428
  }
425
- size_t size = pbBoolSize();
429
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbBoolSize() : pbBoolSize();
426
430
  MMBuffer data(size);
427
431
  CodedOutputData output(data.getPtr(), size);
428
432
  output.writeBool(value);
433
+ if (unlikely(m_enableKeyExpire)) {
434
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
435
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
436
+ } else {
437
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
438
+ }
429
439
 
430
- return setDataForKey(move(data), key);
440
+ return setDataForKey(std::move(data), key);
431
441
  }
432
442
 
433
443
  bool MMKV::set(int32_t value, MMKVKey_t key) {
444
+ return set(value, key, m_expiredInSeconds);
445
+ }
446
+
447
+ bool MMKV::set(int32_t value, MMKVKey_t key, uint32_t expireDuration) {
434
448
  if (isKeyEmpty(key)) {
435
449
  return false;
436
450
  }
437
- size_t size = pbInt32Size(value);
451
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbInt32Size(value) : pbInt32Size(value);
438
452
  MMBuffer data(size);
439
453
  CodedOutputData output(data.getPtr(), size);
440
454
  output.writeInt32(value);
455
+ if (unlikely(m_enableKeyExpire)) {
456
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
457
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
458
+ } else {
459
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
460
+ }
441
461
 
442
- return setDataForKey(move(data), key);
462
+ return setDataForKey(std::move(data), key);
443
463
  }
444
464
 
445
465
  bool MMKV::set(uint32_t value, MMKVKey_t key) {
466
+ return set(value, key, m_expiredInSeconds);
467
+ }
468
+
469
+ bool MMKV::set(uint32_t value, MMKVKey_t key, uint32_t expireDuration) {
446
470
  if (isKeyEmpty(key)) {
447
471
  return false;
448
472
  }
449
- size_t size = pbUInt32Size(value);
473
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbUInt32Size(value) : pbUInt32Size(value);
450
474
  MMBuffer data(size);
451
475
  CodedOutputData output(data.getPtr(), size);
452
476
  output.writeUInt32(value);
477
+ if (unlikely(m_enableKeyExpire)) {
478
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
479
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
480
+ } else {
481
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
482
+ }
453
483
 
454
- return setDataForKey(move(data), key);
484
+ return setDataForKey(std::move(data), key);
455
485
  }
456
486
 
457
487
  bool MMKV::set(int64_t value, MMKVKey_t key) {
488
+ return set(value, key, m_expiredInSeconds);
489
+ }
490
+
491
+ bool MMKV::set(int64_t value, MMKVKey_t key, uint32_t expireDuration) {
458
492
  if (isKeyEmpty(key)) {
459
493
  return false;
460
494
  }
461
- size_t size = pbInt64Size(value);
495
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbInt64Size(value) : pbInt64Size(value);
462
496
  MMBuffer data(size);
463
497
  CodedOutputData output(data.getPtr(), size);
464
498
  output.writeInt64(value);
499
+ if (unlikely(m_enableKeyExpire)) {
500
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
501
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
502
+ } else {
503
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
504
+ }
465
505
 
466
- return setDataForKey(move(data), key);
506
+ return setDataForKey(std::move(data), key);
467
507
  }
468
508
 
469
509
  bool MMKV::set(uint64_t value, MMKVKey_t key) {
510
+ return set(value, key, m_expiredInSeconds);
511
+ }
512
+
513
+ bool MMKV::set(uint64_t value, MMKVKey_t key, uint32_t expireDuration) {
470
514
  if (isKeyEmpty(key)) {
471
515
  return false;
472
516
  }
473
- size_t size = pbUInt64Size(value);
517
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbUInt64Size(value) : pbUInt64Size(value);
474
518
  MMBuffer data(size);
475
519
  CodedOutputData output(data.getPtr(), size);
476
520
  output.writeUInt64(value);
521
+ if (unlikely(m_enableKeyExpire)) {
522
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
523
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
524
+ } else {
525
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
526
+ }
477
527
 
478
- return setDataForKey(move(data), key);
528
+ return setDataForKey(std::move(data), key);
479
529
  }
480
530
 
481
531
  bool MMKV::set(float value, MMKVKey_t key) {
532
+ return set(value, key, m_expiredInSeconds);
533
+ }
534
+
535
+ bool MMKV::set(float value, MMKVKey_t key, uint32_t expireDuration) {
482
536
  if (isKeyEmpty(key)) {
483
537
  return false;
484
538
  }
485
- size_t size = pbFloatSize();
539
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbFloatSize() : pbFloatSize();
486
540
  MMBuffer data(size);
487
541
  CodedOutputData output(data.getPtr(), size);
488
542
  output.writeFloat(value);
543
+ if (unlikely(m_enableKeyExpire)) {
544
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
545
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
546
+ } else {
547
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
548
+ }
489
549
 
490
- return setDataForKey(move(data), key);
550
+ return setDataForKey(std::move(data), key);
491
551
  }
492
552
 
493
553
  bool MMKV::set(double value, MMKVKey_t key) {
554
+ return set(value, key, m_expiredInSeconds);
555
+ }
556
+
557
+ bool MMKV::set(double value, MMKVKey_t key, uint32_t expireDuration) {
494
558
  if (isKeyEmpty(key)) {
495
559
  return false;
496
560
  }
497
- size_t size = pbDoubleSize();
561
+ size_t size = unlikely(m_enableKeyExpire) ? Fixed32Size + pbDoubleSize() : pbDoubleSize();
498
562
  MMBuffer data(size);
499
563
  CodedOutputData output(data.getPtr(), size);
500
564
  output.writeDouble(value);
565
+ if (unlikely(m_enableKeyExpire)) {
566
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
567
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
568
+ } else {
569
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
570
+ }
501
571
 
502
- return setDataForKey(move(data), key);
572
+ return setDataForKey(std::move(data), key);
503
573
  }
504
574
 
505
575
  #ifndef MMKV_APPLE
506
576
 
507
577
  bool MMKV::set(const char *value, MMKVKey_t key) {
578
+ return set(value, key, m_expiredInSeconds);
579
+ }
580
+
581
+ bool MMKV::set(const char *value, MMKVKey_t key, uint32_t expireDuration) {
508
582
  if (!value) {
509
583
  removeValueForKey(key);
510
584
  return true;
511
585
  }
512
- return setDataForKey(MMBuffer((void *) value, strlen(value), MMBufferNoCopy), key, true);
586
+ if (likely(!m_enableKeyExpire)) {
587
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
588
+ return setDataForKey(MMBuffer((void *) value, strlen(value), MMBufferNoCopy), key, true);
589
+ } else {
590
+ MMBuffer data((void *) value, strlen(value), MMBufferNoCopy);
591
+ if (data.length() > 0) {
592
+ auto tmp = MMBuffer(pbMMBufferSize(data) + Fixed32Size);
593
+ CodedOutputData output(tmp.getPtr(), tmp.length());
594
+ output.writeData(data);
595
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
596
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
597
+ data = std::move(tmp);
598
+ }
599
+ return setDataForKey(std::move(data), key);
600
+ }
513
601
  }
514
602
 
515
603
  bool MMKV::set(const string &value, MMKVKey_t key) {
604
+ return set(value, key, m_expiredInSeconds);
605
+ }
606
+
607
+ bool MMKV::set(const string &value, MMKVKey_t key, uint32_t expireDuration) {
516
608
  if (isKeyEmpty(key)) {
517
609
  return false;
518
610
  }
519
- return setDataForKey(MMBuffer((void *) value.data(), value.length(), MMBufferNoCopy), key, true);
611
+ if (likely(!m_enableKeyExpire)) {
612
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
613
+ return setDataForKey(MMBuffer((void *) value.data(), value.length(), MMBufferNoCopy), key, true);
614
+ } else {
615
+ MMBuffer data((void *) value.data(), value.length(), MMBufferNoCopy);
616
+ if (data.length() > 0) {
617
+ auto tmp = MMBuffer(pbMMBufferSize(data) + Fixed32Size);
618
+ CodedOutputData output(tmp.getPtr(), tmp.length());
619
+ output.writeData(data);
620
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
621
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
622
+ data = std::move(tmp);
623
+ }
624
+ return setDataForKey(std::move(data), key);
625
+ }
520
626
  }
521
627
 
522
628
  bool MMKV::set(const MMBuffer &value, MMKVKey_t key) {
629
+ return set(value, key, m_expiredInSeconds);
630
+ }
631
+
632
+ bool MMKV::set(const MMBuffer &value, MMKVKey_t key, uint32_t expireDuration) {
523
633
  if (isKeyEmpty(key)) {
524
634
  return false;
525
635
  }
526
636
  // delay write the size needed for encoding value
527
637
  // avoid memory copying
528
- return setDataForKey(MMBuffer(value.getPtr(), value.length(), MMBufferNoCopy), key, true);
638
+ if (likely(!m_enableKeyExpire)) {
639
+ assert(expireDuration == ExpireNever && "setting expire duration without calling enableAutoKeyExpire() first");
640
+ return setDataForKey(MMBuffer(value.getPtr(), value.length(), MMBufferNoCopy), key, true);
641
+ } else {
642
+ MMBuffer data(value.getPtr(), value.length(), MMBufferNoCopy);
643
+ if (data.length() > 0) {
644
+ auto tmp = MMBuffer(pbMMBufferSize(data) + Fixed32Size);
645
+ CodedOutputData output(tmp.getPtr(), tmp.length());
646
+ output.writeData(data);
647
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
648
+ output.writeRawLittleEndian32(UInt32ToInt32(time));
649
+ data = std::move(tmp);
650
+ }
651
+ return setDataForKey(std::move(data), key);
652
+ }
653
+ }
654
+
655
+ bool MMKV::set(const vector<string> &value, MMKVKey_t key) {
656
+ return set(value, key, m_expiredInSeconds);
529
657
  }
530
658
 
531
- bool MMKV::set(const vector<string> &v, MMKVKey_t key) {
659
+ bool MMKV::set(const vector<string> &v, MMKVKey_t key, uint32_t expireDuration) {
532
660
  if (isKeyEmpty(key)) {
533
661
  return false;
534
662
  }
535
663
  auto data = MiniPBCoder::encodeDataWithObject(v);
536
- return setDataForKey(move(data), key);
664
+ if (unlikely(m_enableKeyExpire) && data.length() > 0) {
665
+ auto tmp = MMBuffer(data.length() + Fixed32Size);
666
+ auto ptr = (uint8_t *)tmp.getPtr();
667
+ memcpy(ptr, data.getPtr(), data.length());
668
+ auto time = (expireDuration != ExpireNever) ? getCurrentTimeInSecond() + expireDuration : ExpireNever;
669
+ memcpy(ptr + data.length(), &time, Fixed32Size);
670
+ data = std::move(tmp);
671
+ }
672
+ return setDataForKey(std::move(data), key);
537
673
  }
538
674
 
539
675
  bool MMKV::getString(MMKVKey_t key, string &result) {
@@ -565,7 +701,7 @@ bool MMKV::getBytes(MMKVKey_t key, mmkv::MMBuffer &result) {
565
701
  if (data.length() > 0) {
566
702
  try {
567
703
  CodedInputData input(data.getPtr(), data.length());
568
- result = move(input.readData());
704
+ result = std::move(input.readData());
569
705
  return true;
570
706
  } catch (std::exception &exception) {
571
707
  MMKVError("%s", exception.what());
@@ -864,11 +1000,15 @@ bool MMKV::containsKey(MMKVKey_t key) {
864
1000
  SCOPED_LOCK(m_lock);
865
1001
  checkLoadData();
866
1002
 
867
- if (m_crypter) {
868
- return m_dicCrypt->find(key) != m_dicCrypt->end();
869
- } else {
870
- return m_dic->find(key) != m_dic->end();
1003
+ if (likely(!m_enableKeyExpire)) {
1004
+ if (m_crypter) {
1005
+ return m_dicCrypt->find(key) != m_dicCrypt->end();
1006
+ } else {
1007
+ return m_dic->find(key) != m_dic->end();
1008
+ }
871
1009
  }
1010
+ auto raw = getDataWithoutMTimeForKey(key);
1011
+ return raw.length() != 0;
872
1012
  }
873
1013
 
874
1014
  size_t MMKV::count() {
@@ -999,7 +1139,7 @@ static bool backupOneToDirectoryByFilePath(const string &mmapKey, const MMKVPath
999
1139
  bool ret = false;
1000
1140
  {
1001
1141
  #ifdef MMKV_WIN32
1002
- MMKVInfo("backup one mmkv[%s] from [%ws] to [%ws]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1142
+ MMKVInfo("backup one mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1003
1143
  #else
1004
1144
  MMKVInfo("backup one mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1005
1145
  #endif
@@ -1039,7 +1179,7 @@ bool MMKV::backupOneToDirectory(const string &mmapKey, const MMKVPath_t &dstPath
1039
1179
  // get one in cache, do it the easy way
1040
1180
  if (kv) {
1041
1181
  #ifdef MMKV_WIN32
1042
- MMKVInfo("backup one cached mmkv[%s] from [%ws] to [%ws]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1182
+ MMKVInfo("backup one cached mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1043
1183
  #else
1044
1184
  MMKVInfo("backup one cached mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1045
1185
  #endif
@@ -1113,7 +1253,7 @@ size_t MMKV::backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t &sr
1113
1253
  auto srcCRCPath = srcPath + CRC_SUFFIX;
1114
1254
  if (mmapIDCRCSet.find(srcCRCPath) == mmapIDCRCSet.end()) {
1115
1255
  #ifdef MMKV_WIN32
1116
- MMKVWarning("crc not exist [%ws]", srcCRCPath.c_str());
1256
+ MMKVWarning("crc not exist [%ls]", srcCRCPath.c_str());
1117
1257
  #else
1118
1258
  MMKVWarning("crc not exist [%s]", srcCRCPath.c_str());
1119
1259
  #endif
@@ -1150,7 +1290,7 @@ size_t MMKV::backupAllToDirectory(const MMKVPath_t &dstDir, const MMKVPath_t *sr
1150
1290
 
1151
1291
  static bool restoreOneFromDirectoryByFilePath(const string &mmapKey, const MMKVPath_t &srcPath, const MMKVPath_t &dstPath) {
1152
1292
  auto dstCRCPath = dstPath + CRC_SUFFIX;
1153
- File dstCRCFile(move(dstCRCPath), OpenFlag::ReadWrite | OpenFlag::Create);
1293
+ File dstCRCFile(std::move(dstCRCPath), OpenFlag::ReadWrite | OpenFlag::Create);
1154
1294
  if (!dstCRCFile.isFileValid()) {
1155
1295
  return false;
1156
1296
  }
@@ -1158,7 +1298,7 @@ static bool restoreOneFromDirectoryByFilePath(const string &mmapKey, const MMKVP
1158
1298
  bool ret = false;
1159
1299
  {
1160
1300
  #ifdef MMKV_WIN32
1161
- MMKVInfo("restore one mmkv[%s] from [%ws] to [%ws]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1301
+ MMKVInfo("restore one mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1162
1302
  #else
1163
1303
  MMKVInfo("restore one mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1164
1304
  #endif
@@ -1200,7 +1340,7 @@ bool MMKV::restoreOneFromDirectory(const string &mmapKey, const MMKVPath_t &srcP
1200
1340
  // get one in cache, do it the easy way
1201
1341
  if (kv) {
1202
1342
  #ifdef MMKV_WIN32
1203
- MMKVInfo("restore one cached mmkv[%s] from [%ws] to [%ws]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1343
+ MMKVInfo("restore one cached mmkv[%s] from [%ls] to [%ls]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1204
1344
  #else
1205
1345
  MMKVInfo("restore one cached mmkv[%s] from [%s] to [%s]", mmapKey.c_str(), srcPath.c_str(), dstPath.c_str());
1206
1346
  #endif
@@ -1267,7 +1407,7 @@ size_t MMKV::restoreAllFromDirectory(const MMKVPath_t &srcDir, const MMKVPath_t
1267
1407
  auto srcCRCPath = srcPath + CRC_SUFFIX;
1268
1408
  if (mmapIDCRCSet.find(srcCRCPath) == mmapIDCRCSet.end()) {
1269
1409
  #ifdef MMKV_WIN32
1270
- MMKVWarning("crc not exist [%ws]", srcCRCPath.c_str());
1410
+ MMKVWarning("crc not exist [%ls]", srcCRCPath.c_str());
1271
1411
  #else
1272
1412
  MMKVWarning("crc not exist [%s]", srcCRCPath.c_str());
1273
1413
  #endif