This is an automated email from the ASF dual-hosted git repository.

lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git


The following commit(s) were added to refs/heads/master by this push:
     new 5d444c508 [test] add random test case for manifest file full 
compaction (#4326)
5d444c508 is described below

commit 5d444c508c5fe35b29c89c6fdebe28f3131c1dcf
Author: LsomeYeah <[email protected]>
AuthorDate: Tue Oct 15 17:22:59 2024 +0800

    [test] add random test case for manifest file full compaction (#4326)
---
 .../paimon/manifest/ManifestFileMetaTest.java      | 105 +++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git 
a/paimon-core/src/test/java/org/apache/paimon/manifest/ManifestFileMetaTest.java
 
b/paimon-core/src/test/java/org/apache/paimon/manifest/ManifestFileMetaTest.java
index c3d6cc3be..32b64aa7e 100644
--- 
a/paimon-core/src/test/java/org/apache/paimon/manifest/ManifestFileMetaTest.java
+++ 
b/paimon-core/src/test/java/org/apache/paimon/manifest/ManifestFileMetaTest.java
@@ -39,8 +39,10 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
 import java.util.concurrent.ThreadLocalRandom;
@@ -446,6 +448,109 @@ public class ManifestFileMetaTest extends 
ManifestFileMetaTestBase {
         containSameIdentifyEntryFile(fullCompacted, entryIdentifierExpected);
     }
 
+    @RepeatedTest(100)
+    public void testRandomFullCompaction() throws Exception {
+        List<ManifestFileMeta> input = new ArrayList<>();
+        Set<FileEntry.Identifier> manifestEntrySet = new HashSet<>();
+        Set<FileEntry.Identifier> deleteManifestEntrySet = new HashSet<>();
+        int inputSize = ThreadLocalRandom.current().nextInt(100) + 1;
+        int totalEntryNums = 0;
+        for (int i = 0; i < inputSize; i++) {
+            int entryNums = ThreadLocalRandom.current().nextInt(100) + 1;
+            input.add(
+                    generateRandomData(
+                            entryNums, totalEntryNums, manifestEntrySet, 
deleteManifestEntrySet));
+            totalEntryNums += entryNums;
+        }
+        int suggerstSize = ThreadLocalRandom.current().nextInt(3000) + 1;
+        int sizeTrigger = ThreadLocalRandom.current().nextInt(40000) + 1;
+        List<ManifestFileMeta> newMetas = new ArrayList<>();
+        Optional<List<ManifestFileMeta>> fullCompacted =
+                ManifestFileMerger.tryFullCompaction(
+                        input,
+                        newMetas,
+                        manifestFile,
+                        suggerstSize,
+                        sizeTrigger,
+                        getPartitionType(),
+                        null);
+
+        // *****verify result*****
+        List<ManifestFileMeta> mustMergedFiles =
+                input.stream()
+                        .filter(
+                                manifest ->
+                                        manifest.fileSize() < suggerstSize
+                                                || manifest.numDeletedFiles() 
> 0)
+                        .collect(Collectors.toList());
+        long mustMergeSize =
+                
mustMergedFiles.stream().map(ManifestFileMeta::fileSize).reduce(0L, Long::sum);
+        // manifest files which were not written after full compaction
+        List<ManifestFileMeta> notMergedFiles =
+                input.stream()
+                        .filter(
+                                manifest ->
+                                        manifest.fileSize() >= suggerstSize
+                                                && manifest.numDeletedFiles() 
== 0)
+                        .filter(
+                                manifest ->
+                                        manifestFile.read(manifest.fileName(), 
manifest.fileSize())
+                                                .stream()
+                                                .map(ManifestEntry::identifier)
+                                                
.noneMatch(deleteManifestEntrySet::contains))
+                        .collect(Collectors.toList());
+
+        if (mustMergeSize < sizeTrigger) {
+            assertThat(fullCompacted).isEmpty();
+            assertThat(newMetas).isEmpty();
+        } else if (mustMergedFiles.size() <= 1) {
+            assertThat(fullCompacted).isEmpty();
+            assertThat(newMetas).isEmpty();
+        } else {
+            
assertThat(fullCompacted.get().size()).isEqualTo(notMergedFiles.size() + 1);
+            assertThat(newMetas).size().isEqualTo(1);
+        }
+    }
+
+    private ManifestFileMeta generateRandomData(
+            int entryNums,
+            int totalEntryNums,
+            Set<FileEntry.Identifier> manifestEntrySet,
+            Set<FileEntry.Identifier> deleteManifestEntrySet) {
+        List<ManifestEntry> entries = new ArrayList<>();
+        for (int i = 0; i < entryNums; i++) {
+            // 70% add, 30% delete
+            boolean isAdd = ThreadLocalRandom.current().nextInt(10) < 7;
+            if (manifestEntrySet.isEmpty() || isAdd) {
+                String fileName = String.format("file-%d", totalEntryNums + i);
+                Integer partition = ThreadLocalRandom.current().nextInt(10);
+                int level = ThreadLocalRandom.current().nextInt(6);
+                List<String> extraFiles = 
Lists.newArrayList(String.format("index-%s", fileName));
+                byte[] embeddedIndex = new byte[] {1, 2, 3};
+                entries.add(makeEntry(true, fileName, partition, level, 
extraFiles, embeddedIndex));
+            } else {
+                FileEntry.Identifier identifier =
+                        manifestEntrySet.stream()
+                                
.skip(ThreadLocalRandom.current().nextInt(manifestEntrySet.size()))
+                                .findFirst()
+                                .get();
+                entries.add(
+                        makeEntry(
+                                false,
+                                identifier.fileName,
+                                identifier.partition.getInt(0),
+                                identifier.level,
+                                identifier.extraFiles,
+                                new byte[] {1, 2, 3}));
+                manifestEntrySet.remove(identifier);
+                deleteManifestEntrySet.add(identifier);
+            }
+        }
+        manifestEntrySet.addAll(
+                
entries.stream().map(ManifestEntry::identifier).collect(Collectors.toSet()));
+        return makeManifest(entries.toArray(new ManifestEntry[0]));
+    }
+
     private void createData(
             int numLastBits, List<ManifestFileMeta> input, 
List<ManifestFileMeta> expected) {
         // suggested size 500 and suggested count 3

Reply via email to