void invalidateCache(
      final @Nonnull PartialPath devicePath, final boolean isMultiLevelWildcardMeasurement) {
    if (!devicePath.hasWildcard()) {
      final IDeviceID deviceID = devicePath.getIDeviceID();
      dualKeyCache.invalidate(new TableId(null, deviceID.getTableName()), deviceID);
    } else {
      // This may take quite a long time to perform, yet we assume that the "invalidateLastCache" is
      // only called by deletions, which has a low frequency; and it has avoided that
      // the un-related paths being cleared, like "root.*.b.c.**" affects
      // "root.*.d.c.**", thereby lower the query performance.
      dualKeyCache.invalidate(
          tableId -> {
            try {
              return devicePath.matchPrefixPath(new PartialPath(tableId.getTableName()));
            } catch (final IllegalPathException e) {
              logger.warn(
                  "Illegal tableID {} found in cache when invalidating by path {}, invalidate it anyway",
                  tableId.getTableName(),
                  devicePath);
              return true;
            }
          },
          cachedDeviceID -> {
            try {
              return isMultiLevelWildcardMeasurement
                  ? devicePath.matchPrefixPath(new PartialPath(cachedDeviceID))
                  : devicePath.matchFullPath(new PartialPath(cachedDeviceID));
            } catch (final IllegalPathException e) {
              logger.warn(
                  "Illegal deviceID {} found in cache when invalidating by path {}, invalidate it anyway",
                  cachedDeviceID,
                  devicePath);
              return true;
            }
          });
    }
  }
Invalidate the last cache of one device.

@param database the device's database, without "root"
@param deviceId IDeviceID
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/cache/TableDeviceSchemaCache.java