JingsongLi commented on code in PR #8356:
URL: https://github.com/apache/paimon/pull/8356#discussion_r3475105886


##########
paimon-core/src/main/java/org/apache/paimon/mergetree/LookupLevels.java:
##########
@@ -144,29 +147,84 @@ private T lookup(InternalRow key, SortedRun level) throws 
IOException {
 
     @Nullable
     private T lookup(InternalRow key, DataFileMeta file) throws IOException {
-        LookupFile lookupFile = lookupFileCache.getIfPresent(file.fileName());
+        byte[] keyBytes = serializeKey(key);
+        LookupResult lookupResult = lookupFile(file, keyBytes);
+        byte[] valueBytes = lookupResult.valueBytes;
+        if (valueBytes == null) {
+            return null;
+        }
 
-        boolean newCreatedLookupFile = false;
-        if (lookupFile == null) {
-            lookupFile = createLookupFile(file);
-            newCreatedLookupFile = true;
+        return readFromDisk(
+                getOrCreateProcessor(lookupResult.schemaId, 
lookupResult.serVersion),
+                key,
+                lookupResult.level,
+                valueBytes,
+                file.fileName());
+    }
+
+    private LookupResult lookupFile(DataFileMeta file, byte[] keyBytes) throws 
IOException {
+        String fileName = file.fileName();
+        LookupFile lookupFile = lookupFileCache.getIfPresent(fileName);
+        LookupResult lookupResult = lookupCachedFile(fileName, lookupFile, 
keyBytes);
+        if (lookupResult != null) {
+            return lookupResult;
         }
 
-        byte[] valueBytes;
-        try {
-            byte[] keyBytes = keySerializer.serializeToBytes(key);
-            valueBytes = lookupFile.get(keyBytes);
-        } finally {
-            if (newCreatedLookupFile) {
-                addLocalFile(file, lookupFile);
+        Object lock = lookupFileLocks.computeIfAbsent(fileName, ignored -> new 
Object());
+        synchronized (lock) {
+            try {
+                lookupFile = lookupFileCache.getIfPresent(fileName);
+                lookupResult = lookupCachedFile(fileName, lookupFile, 
keyBytes);
+                if (lookupResult != null) {
+                    return lookupResult;
+                }
+
+                lookupFile = createLookupFile(file);
+
+                try {
+                    return LookupResult.of(lookupFile, 
lookupFile.get(keyBytes));
+                } finally {
+                    addLocalFile(file, lookupFile);
+                }
+            } finally {
+                lookupFileLocks.remove(fileName, lock);

Review Comment:
   Removing the per-file lock here can split synchronization while other 
threads are already waiting on the old lock. If the first creator fails, or the 
newly-created lookup file is immediately evicted because of the disk-size 
limit, a later caller can install a new lock while an older waiter continues 
under the removed lock; then two creators may run for the same data file. With 
deterministic local file names this can surface as `createNewFile()` failures. 
Consider a ref-counted/striped keyed lock or a single-flight `Future` entry 
that is not removed until no waiters remain.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to