blob: 38891d16703511a1cc10eb81aa750b7c998b6e53 [file] [log] [blame]
/*
* 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.drill.exec.store.parquet.metadata;
import com.google.common.base.Preconditions;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableSortedSet;
import org.apache.drill.common.exceptions.DrillRuntimeException;
import java.util.SortedSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MetadataVersion implements Comparable<MetadataVersion> {
private static final String FORMAT = "v?((?!0)\\d+)(\\.(\\d+))?";
private static final Pattern PATTERN = Pattern.compile(FORMAT);
private final int major;
private final int minor;
public MetadataVersion(int major, int minor) {
this.major = major;
this.minor = minor;
}
public MetadataVersion(String metadataVersion) {
Matcher matcher = PATTERN.matcher(metadataVersion);
if (!matcher.matches()) {
throw DrillRuntimeException.create(
"Could not parse metadata version '%s' using format '%s'", metadataVersion, FORMAT);
}
this.major = Integer.parseInt(matcher.group(1));
this.minor = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0;
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof MetadataVersion)) {
return false;
}
MetadataVersion that = (MetadataVersion) o;
return this.major == that.major
&& this.minor == that.minor;
}
@Override
public int hashCode() {
int result = major;
result = 31 * result + minor;
return result;
}
/**
* @return string representation of the metadata file version, for example: "1", "10", "4.13"
* <p>
* String metadata version consists of the following characters:<p>
* major metadata version (any number of digits, except a single zero digit),<p>
* optional "." delimiter (used if minor metadata version is specified),<p>
* minor metadata version (not specified for "0" minor version)
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(major);
if (minor != 0) {
builder.append(".").append(minor);
}
return builder.toString();
}
@Override
public int compareTo(MetadataVersion o) {
Preconditions.checkNotNull(o);
return ComparisonChain.start()
.compare(this.major, o.major)
.compare(this.minor, o.minor)
.result();
}
/**
* Check if this version is at least (equals or higher) the one
* identified by {@code major} and {@code minor} versions integer literals.
*
* @param major major version
* @param minor minor version
* @return {@literal true} if the version is equal to or higher than
* the one it is being checked against
*/
public boolean isAtLeast(int major, int minor) {
return this.major > major || (this.major == major && this.minor >= minor);
}
/**
* Check if the version is the same as the one identified by
* {@code major} and {@code minor} versions integer literals.
*
* @param major major version
* @param minor minor version
* @return {@literal true} if the version is equal to the one
* it is being checked against
*/
public boolean isEqualTo(int major, int minor) {
return this.major == major && this.minor == minor;
}
/**
* Check if this version comes after the one identified by {@code major}
* and {@code minor} versions integer literals. That is, this one was introduced later.
*
* @param major major version
* @param minor minor version
* @return {@literal true} if the version is defined later than
* the one it is being checked against
*/
public boolean isHigherThan(int major, int minor) {
return this.major > major || (this.major == major && this.minor > minor);
}
/**
* Supported metadata versions.
* <p>
* Note: keep them synchronized with {@link org.apache.drill.exec.store.parquet.metadata.MetadataBase.ParquetTableMetadataBase} versions
*/
public static class Constants {
/**
* Version 1: Introduces parquet file metadata caching.<br>
* See DRILL-2743
*/
public static final String V1 = "v1";
/**
* Version 2: Metadata cache file size is reduced.<br>
* See DRILL-4053
*/
public static final String V2 = "v2";
/**
* Version 3: Difference between v3 and v2 : min/max, type_length, precision, scale, repetitionLevel, definitionLevel.<br>
* Filter pushdown for Parquet is implemented. <br>
* See DRILL-1950
*/
public static final String V3 = "v3";
/**
* Version 3.1: Absolute paths of files and directories are replaced with relative ones. Metadata version value
* doesn't contain `v` letter<br>
* See DRILL-3867, DRILL-5660
*/
public static final String V3_1 = "3.1";
/**
* Version 3.2: An array with the components of the field name in
* {@link org.apache.drill.exec.store.parquet.metadata.Metadata_V3.ColumnTypeMetadata_v3.Key} class is replaced by the {@link org.apache.drill.common.expression.SchemaPath}.<br>
* See DRILL-4264
*/
public static final String V3_2 = "3.2";
/**
* Version 3.3: Changed serialization of BINARY and FIXED_LEN_BYTE_ARRAY fields.<br>
* See DRILL-4139
*/
public static final String V3_3 = "3.3";
/**
* Version 4.0: Split the metadata cache file into summary and file metadata
*/
public static final String V4 = "4.0";
/**
* Version 4.1: Added parents' original types in {@link Metadata_V4.ColumnTypeMetadata_v4}
* and {@link Metadata_V4.ColumnMetadata_v4}
*/
public static final String V4_1 = "4.1";
/**
* Version 4.2: Added {@link org.apache.parquet.schema.Type.Repetition} to {@link Metadata_V4.ColumnTypeMetadata_v4}.
*/
public static final String V4_2 = "4.2";
/**
* All historical versions of the Drill metadata cache files. In case of introducing a new parquet metadata version
* please follow the {@link MetadataVersion#FORMAT}.
*/
public static final SortedSet<MetadataVersion> SUPPORTED_VERSIONS = ImmutableSortedSet.of(
new MetadataVersion(V1),
new MetadataVersion(V2),
new MetadataVersion(V3),
new MetadataVersion(V3_1),
new MetadataVersion(V3_2),
new MetadataVersion(V3_3),
new MetadataVersion(V4),
new MetadataVersion(V4_1),
new MetadataVersion(V4_2)
);
/**
* @param metadataVersion string representation of the parquet metadata version
* @return true if metadata version is supported, false otherwise
*/
public static boolean isVersionSupported(String metadataVersion) {
return SUPPORTED_VERSIONS.contains(new MetadataVersion(metadataVersion));
}
}
}