Skip to content

Conversation

@kabo87777
Copy link

Fix Non-Deterministic Behavior in NewReadChunkCompactionPerformerWithAlignedSeriesTest

Problem

Thirteen tests in NewReadChunkCompactionPerformerWithAlignedSeriesTest were failing non-deterministically under NonDex due to order-dependent measurement schema comparisons:

  • testCompactionWithAllDeletion
  • testCompactionWithDeletion
  • testCompactionWithDeletionAndEmptyPage
  • testCompactionWithPartialDeletion
  • testCompactionWithPartialDeletionAndEmptyPage
  • testSimpleCompaction
  • testSimpleCompactionByFlushChunk
  • testSimpleCompactionWithEmptyChunk
  • testSimpleCompactionWithEmptyPage
  • testSimpleCompactionWithNullValue
  • testSimpleCompactionWithNullValueAndEmptyChunk
  • testSimpleCompactionWithNullValueAndEmptyPage
  • testSimpleCompactionWithSomeDeviceNotInTargetFile

Way to Reproduce

cd iotdb-core/datanode
mvn edu.illinois:nondex-maven-plugin:2.1.7:nondex \
  -Dtest=NewReadChunkCompactionPerformerWithAlignedSeriesTest \
  -DnondexRuns=3 -Drat.skip=true
# Result: Multiple failures due to non-deterministic measurement order

Root Cause

The CompactionCheckerUtils.getAllPathsOfResources() method used HashSet for storing paths and did not sort measurement schemas before constructing AlignedFullPath objects:

Set<IFullPath> paths = new HashSet<>();  // Non-deterministic iteration order
// ...
List<IMeasurementSchema> measurementSchemas = new ArrayList<>(schemaMap.values());  // Unsorted
// ...
seriesPath = new AlignedFullPath(deviceID, existedMeasurements, measurementSchemas);

The schemaMap is backed by ConcurrentHashMap which has non-deterministic iteration order. When NonDex shuffled collection order, measurements appeared in different positions within AlignedFullPath, causing data comparison assertions to fail even though the compaction results were semantically correct.

Solution

Made measurement ordering deterministic by sorting schemas and using ordered collections.

Changes Made

Before (Order-Dependent):

Set<IFullPath> paths = new HashSet<>();
// ...
List<IMeasurementSchema> measurementSchemas = new ArrayList<>(schemaMap.values());

After (Order-Independent):

Set<IFullPath> paths = new LinkedHashSet<>();
// ...
List<IMeasurementSchema> measurementSchemas =
    schemaMap.values().stream()
        .sorted(Comparator.comparing(IMeasurementSchema::getMeasurementName))
        .collect(Collectors.toList());

Key Improvements

  • Changed HashSet to LinkedHashSet to preserve insertion order for deterministic iteration
  • Added sorting of measurement schemas by measurement name using Comparator.comparing()
  • Ensures AlignedFullPath objects always have measurements in consistent alphabetical order
  • Added java.util.Comparator import

Verification

mvn edu.illinois:nondex-maven-plugin:2.1.7:nondex \
  -Dtest=NewReadChunkCompactionPerformerWithAlignedSeriesTest \
  -DnondexRuns=3 -Drat.skip=true
# Result: All 15 tests pass across 3 different random seeds (933178, 974622, 1016066)

Key Changed Classes

  • CompactionCheckerUtils: Modified getAllPathsOfResources() method (~10 lines), test utility changes only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant