You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by bl...@apache.org on 2019/06/18 22:16:31 UTC
[incubator-iceberg] branch master updated: Fix concurrent access to
lazy PartitionSpec methods (#219)
This is an automated email from the ASF dual-hosted git repository.
blue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-iceberg.git
The following commit(s) were added to refs/heads/master by this push:
new 33b4db6 Fix concurrent access to lazy PartitionSpec methods (#219)
33b4db6 is described below
commit 33b4db66261d68428a3e7ceb55f0b9b6718e133b
Author: Ryan Blue <rd...@users.noreply.github.com>
AuthorDate: Tue Jun 18 15:16:27 2019 -0700
Fix concurrent access to lazy PartitionSpec methods (#219)
---
.../java/org/apache/iceberg/PartitionSpec.java | 57 ++++++++++++++--------
1 file changed, 38 insertions(+), 19 deletions(-)
diff --git a/api/src/main/java/org/apache/iceberg/PartitionSpec.java b/api/src/main/java/org/apache/iceberg/PartitionSpec.java
index 3d7475b..5013119 100644
--- a/api/src/main/java/org/apache/iceberg/PartitionSpec.java
+++ b/api/src/main/java/org/apache/iceberg/PartitionSpec.java
@@ -55,10 +55,10 @@ public class PartitionSpec implements Serializable {
// this is ordered so that DataFile has a consistent schema
private final int specId;
private final PartitionField[] fields;
- private transient ListMultimap<Integer, PartitionField> fieldsBySourceId = null;
- private transient Map<String, PartitionField> fieldsByName = null;
- private transient Class<?>[] lazyJavaClasses = null;
- private transient List<PartitionField> fieldList = null;
+ private transient volatile ListMultimap<Integer, PartitionField> fieldsBySourceId = null;
+ private transient volatile Map<String, PartitionField> fieldsByName = null;
+ private transient volatile Class<?>[] lazyJavaClasses = null;
+ private transient volatile List<PartitionField> fieldList = null;
private PartitionSpec(Schema schema, int specId, List<PartitionField> fields) {
this.schema = schema;
@@ -118,12 +118,18 @@ public class PartitionSpec implements Serializable {
public Class<?>[] javaClasses() {
if (lazyJavaClasses == null) {
- this.lazyJavaClasses = new Class<?>[fields.length];
- for (int i = 0; i < fields.length; i += 1) {
- PartitionField field = fields[i];
- Type sourceType = schema.findType(field.sourceId());
- Type result = field.transform().getResultType(sourceType);
- lazyJavaClasses[i] = result.typeId().javaClass();
+ synchronized (this) {
+ if (lazyJavaClasses == null) {
+ Class<?>[] classes = new Class<?>[fields.length];
+ for (int i = 0; i < fields.length; i += 1) {
+ PartitionField field = fields[i];
+ Type sourceType = schema.findType(field.sourceId());
+ Type result = field.transform().getResultType(sourceType);
+ classes[i] = result.typeId().javaClass();
+ }
+
+ this.lazyJavaClasses = classes;
+ }
}
}
@@ -209,18 +215,26 @@ public class PartitionSpec implements Serializable {
private List<PartitionField> lazyFieldList() {
if (fieldList == null) {
- this.fieldList = ImmutableList.copyOf(fields);
+ synchronized (this) {
+ if (fieldList == null) {
+ this.fieldList = ImmutableList.copyOf(fields);
+ }
+ }
}
return fieldList;
}
private Map<String, PartitionField> lazyFieldsByName() {
if (fieldsByName == null) {
- ImmutableMap.Builder<String, PartitionField> builder = ImmutableMap.builder();
- for (PartitionField field : fields) {
- builder.put(field.name(), field);
+ synchronized (this) {
+ if (fieldsByName == null) {
+ ImmutableMap.Builder<String, PartitionField> builder = ImmutableMap.builder();
+ for (PartitionField field : fields) {
+ builder.put(field.name(), field);
+ }
+ this.fieldsByName = builder.build();
+ }
}
- this.fieldsByName = builder.build();
}
return fieldsByName;
@@ -228,10 +242,15 @@ public class PartitionSpec implements Serializable {
private ListMultimap<Integer, PartitionField> lazyFieldsBySourceId() {
if (fieldsBySourceId == null) {
- this.fieldsBySourceId = Multimaps
- .newListMultimap(Maps.newHashMap(), () -> Lists.newArrayListWithCapacity(fields.length));
- for (PartitionField field : fields) {
- fieldsBySourceId.put(field.sourceId(), field);
+ synchronized (this) {
+ if (fieldsBySourceId == null) {
+ ListMultimap<Integer, PartitionField> multiMap = Multimaps
+ .newListMultimap(Maps.newHashMap(), () -> Lists.newArrayListWithCapacity(fields.length));
+ for (PartitionField field : fields) {
+ multiMap.put(field.sourceId(), field);
+ }
+ this.fieldsBySourceId = multiMap;
+ }
}
}