This is an automated email from the ASF dual-hosted git repository.
gabor pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/parquet-java.git
The following commit(s) were added to refs/heads/master by this push:
new 9db623654 GH-3224: Make ParquetProperties.valuesWriterFactory thread
safe (#3308)
9db623654 is described below
commit 9db62365453e3f08082162b92598b7ee56e38e0b
Author: Arnav Balyan <[email protected]>
AuthorDate: Tue Sep 16 18:21:34 2025 +0530
GH-3224: Make ParquetProperties.valuesWriterFactory thread safe (#3308)
---
.../apache/parquet/column/ParquetProperties.java | 7 +++-
.../column/ParquetPropertiesThreadSafetyTest.java | 46 ++++++++++++++++++++++
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git
a/parquet-column/src/main/java/org/apache/parquet/column/ParquetProperties.java
b/parquet-column/src/main/java/org/apache/parquet/column/ParquetProperties.java
index d3dced53d..f29214b45 100644
---
a/parquet-column/src/main/java/org/apache/parquet/column/ParquetProperties.java
+++
b/parquet-column/src/main/java/org/apache/parquet/column/ParquetProperties.java
@@ -69,6 +69,11 @@ public class ParquetProperties {
public static final boolean DEFAULT_PAGE_WRITE_CHECKSUM_ENABLED = true;
+ /**
+ * @deprecated This shared instance can cause thread safety issues when used
by multiple builders concurrently.
+ * Use {@code new DefaultValuesWriterFactory()} instead to create individual
instances.
+ */
+ @Deprecated
public static final ValuesWriterFactory DEFAULT_VALUES_WRITER_FACTORY = new
DefaultValuesWriterFactory();
private static final int MIN_SLAB_SIZE = 64;
@@ -396,7 +401,7 @@ public class ParquetProperties {
private int pageValueCountThreshold = DEFAULT_PAGE_VALUE_COUNT_THRESHOLD;
private boolean estimateNextSizeCheck =
DEFAULT_ESTIMATE_ROW_COUNT_FOR_PAGE_SIZE_CHECK;
private ByteBufferAllocator allocator = new HeapByteBufferAllocator();
- private ValuesWriterFactory valuesWriterFactory =
DEFAULT_VALUES_WRITER_FACTORY;
+ private ValuesWriterFactory valuesWriterFactory = new
DefaultValuesWriterFactory();
private int columnIndexTruncateLength =
DEFAULT_COLUMN_INDEX_TRUNCATE_LENGTH;
private int statisticsTruncateLength = DEFAULT_STATISTICS_TRUNCATE_LENGTH;
private boolean statisticsEnabled = DEFAULT_STATISTICS_ENABLED;
diff --git
a/parquet-column/src/test/java/org/apache/parquet/column/ParquetPropertiesThreadSafetyTest.java
b/parquet-column/src/test/java/org/apache/parquet/column/ParquetPropertiesThreadSafetyTest.java
new file mode 100644
index 000000000..bb622f1c1
--- /dev/null
+++
b/parquet-column/src/test/java/org/apache/parquet/column/ParquetPropertiesThreadSafetyTest.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.parquet.column;
+
+import static org.junit.Assert.assertNotSame;
+
+import java.lang.reflect.Field;
+import org.apache.parquet.column.values.factory.ValuesWriterFactory;
+import org.junit.Test;
+
+public class ParquetPropertiesThreadSafetyTest {
+
+ @Test
+ public void testBuilderValuesWriterFactoryNotShared() throws Exception {
+ ParquetProperties.Builder builder1 = ParquetProperties.builder();
+ ParquetProperties.Builder builder2 = ParquetProperties.builder();
+ ParquetProperties.Builder builder3 = ParquetProperties.builder();
+
+ Field factoryField =
ParquetProperties.Builder.class.getDeclaredField("valuesWriterFactory");
+ factoryField.setAccessible(true);
+
+ ValuesWriterFactory factory1 = (ValuesWriterFactory)
factoryField.get(builder1);
+ ValuesWriterFactory factory2 = (ValuesWriterFactory)
factoryField.get(builder2);
+ ValuesWriterFactory factory3 = (ValuesWriterFactory)
factoryField.get(builder3);
+
+ assertNotSame("Builder instances should not share ValuesWriterFactory
instances", factory1, factory2);
+ assertNotSame("Builder instances should not share ValuesWriterFactory
instances", factory2, factory3);
+ assertNotSame("Builder instances should not share ValuesWriterFactory
instances", factory1, factory3);
+ }
+}