removeMany method

  1. @override
Future<int> removeMany(
  1. List<String> keys, {
  2. bool skipCommit = false,
})
override

Bulk delete — removes every key in keys. Returns the count of keys actually removed (race-tolerant: input keys may already have been deleted).

Implementation

@override
Future<int> removeMany(List<String> keys, {bool skipCommit = false}) async {
  if (keys.isEmpty) return 0;
  if (!getBox().isOpen) {
    throw DataStoreException(
        'Failed to bulk-delete. Hive Keystore is not initialized or opened');
  }
  final box = getBox();

  // 1. Identify which input keys are actually present. We dedup by
  //    lowercased form so duplicates in [keys] don't double-count.
  final present = <String>{};
  final preparedToDelete = <String>[];
  for (final raw in keys) {
    final lowered = raw.toLowerCase();
    if (present.contains(lowered)) continue;
    final hiveKey = HiveKeyStoreHelper.prepareKey(lowered);
    if (!box.containsKey(hiveKey)) continue;
    present.add(lowered);
    preparedToDelete.add(hiveKey);
  }
  if (present.isEmpty) return 0;

  // 2. preRemoveHooks per present key.
  for (final lowered in present) {
    for (final hook in preRemoveHooks) {
      await hook(lowered, skipCommit: skipCommit);
    }
  }

  try {
    // 3. Single batched box delete.
    await box.deleteAll(preparedToDelete);

    // 4. Per-key cache + commit-log bookkeeping. The commit-log
    //    steps are no-ops on a commit-log-free keystore.
    final commitLog = _commitLog;
    for (final lowered in present) {
      _expiryKeysCache.remove(lowered);
      if (commitLog == null) continue;
      if (skipCommit) {
        // Match remove(): purge any existing commit entries for this
        // key, otherwise sync may consider them valid post-delete.
        CommitEntry? commitEntry = commitLog.getLatestCommitEntry(lowered);
        if (commitEntry != null) {
          await commitLog.commitLogKeyStore.remove(commitEntry.commitId!);
        }
      } else {
        await commitLog.commit(lowered, CommitOp.DELETE);
      }
    }
  } on Exception catch (exception) {
    logger.severe('HiveAtKeyValueStore removeMany exception: $exception');
    throw DataStoreException(
        'exception in removeMany: ${exception.toString()}');
  } on HiveError catch (error) {
    await _restartHiveBox(error);
    logger.severe('HiveAtKeyValueStore removeMany error: $error');
    throw DataStoreException(error.message);
  }

  // 5. postRemoveHooks per present key.
  for (final lowered in present) {
    for (final hook in postRemoveHooks) {
      await hook(lowered, skipCommit: skipCommit);
    }
  }

  // 6. Emit a KeyRemoved event per actually-removed key.
  for (final lowered in present) {
    _changesController.add(KeyRemoved(lowered));
  }

  return present.length;
}