Skip to content

Commit e7e95df

Browse files
committed
update
1 parent 6d2635b commit e7e95df

7 files changed

Lines changed: 695 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ target
1515
dependency-reduced-pom.xml
1616
.idea/*
1717
target/
18+
examples/data/**
1819
.cache
1920
*~
2021
mvn_install.log
2122
.vscode/*
2223
.DS_Store
23-

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ Parquet-Java has supported Java Vector API to speed up reading, to enable this f
108108
* Edit spark class#VectorizedRleValuesReader, function#readNextGroup refer to parquet class#ParquetReadRouter, function#readBatchUsing512Vector
109109
* Build spark with maven and replace spark-sql_2.12-{VERSION}.jar on the spark jars folder
110110

111+
## Documentation
112+
113+
For comprehensive usage documentation, examples, and tutorials, see:
114+
115+
- **[Examples](examples/)** - Practical examples demonstrating basic and advanced usage
116+
- **[API Reference](examples/README.md)** - Detailed API documentation
117+
111118
## Map/Reduce integration
112119

113120
[Input](https://github.com/apache/parquet-java/blob/master/parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetInputFormat.java) and [Output](https://github.com/apache/parquet-java/blob/master/parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetOutputFormat.java) formats.

examples/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Parquet Java Examples
2+
3+
This directory contains real examples demonstrating how to use the Apache Parquet Java library.
4+
5+
## Examples Overview
6+
7+
### 1. BasicReadWriteExample.java
8+
Demonstrates basic reading and writing of Parquet files using the example API.
9+
10+
- Schema definition
11+
- Writing data with compression
12+
- Reading data and calculating statistics
13+
- Basic configuration options
14+
15+
**Run with:**
16+
```bash
17+
mvn exec:java -Dexec.mainClass="org.apache.parquet.examples.BasicReadWriteExample"
18+
```
19+
20+
### 2. AvroIntegrationExample.java
21+
Shows how to integrate Avro with Parquet format.
22+
23+
- Avro schema definition
24+
- Writing Avro records to Parquet
25+
- Reading Parquet files as Avro records
26+
- Schema projection for performance
27+
28+
**Run with:**
29+
```bash
30+
mvn exec:java -Dexec.mainClass="org.apache.parquet.examples.AvroIntegrationExample"
31+
```
32+
33+
### 3. AdvancedFeaturesExample.java
34+
Demonstrates advanced Parquet features.
35+
36+
- Predicate pushdown filtering
37+
- Performance optimization with projections
38+
- Complex filter conditions
39+
40+
**Run with:**
41+
```bash
42+
mvn exec:java -Dexec.mainClass="org.apache.parquet.examples.AdvancedFeaturesExample"
43+
```
44+
45+
## Prerequisites
46+
47+
- Java 8 or higher
48+
- Maven 3.6+
49+
50+
## Contributing
51+
52+
Feel free to contribute additional examples by:
53+
54+
1. Creating new example classes
55+
2. Improving existing examples
56+
3. Adding more comprehensive test cases
57+
4. Updating documentation

examples/pom.xml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>org.apache.parquet</groupId>
9+
<artifactId>parquet-examples</artifactId>
10+
<version>1.15.1</version>
11+
<packaging>jar</packaging>
12+
13+
<name>Parquet Java Examples</name>
14+
<description>Examples demonstrating how to use the Apache Parquet Java library</description>
15+
16+
<properties>
17+
<maven.compiler.source>8</maven.compiler.source>
18+
<maven.compiler.target>8</maven.compiler.target>
19+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20+
<parquet.version>1.15.1</parquet.version>
21+
<hadoop.version>3.3.4</hadoop.version>
22+
<avro.version>1.11.1</avro.version>
23+
</properties>
24+
25+
<dependencies>
26+
<dependency>
27+
<groupId>org.apache.parquet</groupId>
28+
<artifactId>parquet-common</artifactId>
29+
<version>${parquet.version}</version>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.apache.parquet</groupId>
33+
<artifactId>parquet-encoding</artifactId>
34+
<version>${parquet.version}</version>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.apache.parquet</groupId>
38+
<artifactId>parquet-column</artifactId>
39+
<version>${parquet.version}</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.apache.parquet</groupId>
43+
<artifactId>parquet-hadoop</artifactId>
44+
<version>${parquet.version}</version>
45+
</dependency>
46+
47+
<dependency>
48+
<groupId>org.apache.parquet</groupId>
49+
<artifactId>parquet-avro</artifactId>
50+
<version>${parquet.version}</version>
51+
</dependency>
52+
53+
<dependency>
54+
<groupId>org.apache.parquet</groupId>
55+
<artifactId>parquet-thrift</artifactId>
56+
<version>${parquet.version}</version>
57+
</dependency>
58+
59+
<dependency>
60+
<groupId>org.apache.parquet</groupId>
61+
<artifactId>parquet-protobuf</artifactId>
62+
<version>${parquet.version}</version>
63+
</dependency>
64+
65+
<dependency>
66+
<groupId>org.apache.hadoop</groupId>
67+
<artifactId>hadoop-client</artifactId>
68+
<version>${hadoop.version}</version>
69+
</dependency>
70+
<dependency>
71+
<groupId>org.apache.hadoop</groupId>
72+
<artifactId>hadoop-common</artifactId>
73+
<version>${hadoop.version}</version>
74+
</dependency>
75+
76+
<dependency>
77+
<groupId>org.apache.avro</groupId>
78+
<artifactId>avro</artifactId>
79+
<version>${avro.version}</version>
80+
</dependency>
81+
82+
<dependency>
83+
<groupId>org.xerial.snappy</groupId>
84+
<artifactId>snappy-java</artifactId>
85+
<version>1.1.9.1</version>
86+
</dependency>
87+
88+
<dependency>
89+
<groupId>org.slf4j</groupId>
90+
<artifactId>slf4j-api</artifactId>
91+
<version>1.7.36</version>
92+
</dependency>
93+
<dependency>
94+
<groupId>ch.qos.logback</groupId>
95+
<artifactId>logback-classic</artifactId>
96+
<version>1.2.12</version>
97+
</dependency>
98+
</dependencies>
99+
100+
<build>
101+
<plugins>
102+
<plugin>
103+
<groupId>org.apache.maven.plugins</groupId>
104+
<artifactId>maven-compiler-plugin</artifactId>
105+
<version>3.11.0</version>
106+
<configuration>
107+
<source>8</source>
108+
<target>8</target>
109+
</configuration>
110+
</plugin>
111+
112+
<plugin>
113+
<groupId>org.apache.maven.plugins</groupId>
114+
<artifactId>maven-shade-plugin</artifactId>
115+
<version>3.4.1</version>
116+
<executions>
117+
<execution>
118+
<phase>package</phase>
119+
<goals>
120+
<goal>shade</goal>
121+
</goals>
122+
<configuration>
123+
<transformers>
124+
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
125+
<mainClass>org.apache.parquet.examples.BasicReadWriteExample</mainClass>
126+
</transformer>
127+
</transformers>
128+
</configuration>
129+
</execution>
130+
</executions>
131+
</plugin>
132+
133+
<plugin>
134+
<groupId>org.apache.maven.plugins</groupId>
135+
<artifactId>maven-surefire-plugin</artifactId>
136+
<version>3.1.2</version>
137+
</plugin>
138+
</plugins>
139+
</build>
140+
</project>
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.parquet.examples;
21+
22+
import org.apache.hadoop.fs.Path;
23+
import org.apache.parquet.example.data.Group;
24+
import org.apache.parquet.example.data.simple.SimpleGroupFactory;
25+
import org.apache.parquet.filter2.compat.FilterCompat;
26+
import org.apache.parquet.filter2.predicate.FilterApi;
27+
import org.apache.parquet.filter2.predicate.FilterPredicate;
28+
import org.apache.parquet.filter2.predicate.Operators;
29+
import org.apache.parquet.hadoop.ParquetReader;
30+
import org.apache.parquet.hadoop.ParquetWriter;
31+
import org.apache.parquet.hadoop.example.ExampleParquetWriter;
32+
import org.apache.parquet.hadoop.example.GroupReadSupport;
33+
import org.apache.parquet.hadoop.example.GroupWriteSupport;
34+
import org.apache.parquet.hadoop.metadata.CompressionCodecName;
35+
import org.apache.parquet.schema.MessageType;
36+
import org.apache.parquet.schema.PrimitiveType;
37+
import org.apache.parquet.schema.Types;
38+
39+
import java.io.IOException;
40+
import java.util.Random;
41+
42+
public class AdvancedFeaturesExample {
43+
44+
public static void main(String[] args) throws IOException {
45+
String filename = "data/sales.parquet";
46+
47+
MessageType schema = Types.buildMessage()
48+
.required(PrimitiveType.PrimitiveTypeName.INT32).named("id")
49+
.required(PrimitiveType.PrimitiveTypeName.BINARY).named("product")
50+
.required(PrimitiveType.PrimitiveTypeName.DOUBLE).named("amount")
51+
.required(PrimitiveType.PrimitiveTypeName.BINARY).named("region")
52+
.named("sale");
53+
54+
writeSalesData(filename, schema);
55+
56+
testPredicatePushdown(filename);
57+
58+
testPerformanceOptimization(filename);
59+
}
60+
61+
private static void writeSalesData(String filename, MessageType schema) throws IOException {
62+
Path file = new Path(filename);
63+
64+
try (ParquetWriter<Group> writer = ExampleParquetWriter.builder(file)
65+
.withCompressionCodec(CompressionCodecName.SNAPPY)
66+
.withRowGroupSize(64 * 1024 * 1024)
67+
.withPageSize(1024 * 1024)
68+
.withDictionaryEncoding(true)
69+
.config(GroupWriteSupport.PARQUET_EXAMPLE_SCHEMA, schema.toString())
70+
.build()) {
71+
72+
SimpleGroupFactory factory = new SimpleGroupFactory(schema);
73+
Random random = new Random(42);
74+
String[] products = {"Laptop", "Phone", "Tablet", "Monitor", "Keyboard"};
75+
String[] regions = {"North", "South", "East", "West"};
76+
77+
for (int i = 0; i < 10000; i++) {
78+
Group group = factory.newGroup()
79+
.append("id", i)
80+
.append("product", products[random.nextInt(products.length)])
81+
.append("amount", 100.0 + random.nextDouble() * 900.0)
82+
.append("region", regions[random.nextInt(regions.length)]);
83+
writer.write(group);
84+
}
85+
86+
System.out.println("Wrote 10000 sales records");
87+
}
88+
}
89+
90+
private static void testPredicatePushdown(String filename) throws IOException {
91+
Path file = new Path(filename);
92+
93+
Operators.DoubleColumn amountColumn = FilterApi.doubleColumn("amount");
94+
FilterPredicate amountFilter = FilterApi.gt(amountColumn, 500.0);
95+
96+
long startTime = System.currentTimeMillis();
97+
int count = 0;
98+
try (ParquetReader<Group> reader = ParquetReader.builder(new GroupReadSupport(), file)
99+
.withFilter(FilterCompat.get(amountFilter))
100+
.build()) {
101+
102+
Group group;
103+
while ((group = reader.read()) != null) {
104+
count++;
105+
}
106+
}
107+
long filterTime = System.currentTimeMillis() - startTime;
108+
109+
Operators.BinaryColumn regionColumn = FilterApi.binaryColumn("region");
110+
FilterPredicate complexFilter = FilterApi.and(
111+
FilterApi.gt(amountColumn, 500.0),
112+
FilterApi.eq(regionColumn, org.apache.parquet.io.api.Binary.fromString("North"))
113+
);
114+
115+
startTime = System.currentTimeMillis();
116+
count = 0;
117+
try (ParquetReader<Group> reader = ParquetReader.builder(new GroupReadSupport(), file)
118+
.withFilter(FilterCompat.get(complexFilter))
119+
.build()) {
120+
121+
Group group;
122+
while ((group = reader.read()) != null) {
123+
count++;
124+
}
125+
}
126+
filterTime = System.currentTimeMillis() - startTime;
127+
System.out.printf("Found %d records in %dms%n", count, filterTime);
128+
}
129+
130+
private static void testPerformanceOptimization(String filename) throws IOException {
131+
Path file = new Path(filename);
132+
133+
System.out.println("Testing default reading performance...");
134+
long startTime = System.currentTimeMillis();
135+
int count = 0;
136+
try (ParquetReader<Group> reader = ParquetReader.builder(new GroupReadSupport(), file).build()) {
137+
Group group;
138+
while ((group = reader.read()) != null) {
139+
count++;
140+
}
141+
}
142+
long defaultTime = System.currentTimeMillis() - startTime;
143+
System.out.printf("Default: Read %d records in %dms%n", count, defaultTime);
144+
145+
System.out.println("Testing projection reading performance...");
146+
MessageType projection = Types.buildMessage()
147+
.required(PrimitiveType.PrimitiveTypeName.INT32).named("id")
148+
.required(PrimitiveType.PrimitiveTypeName.DOUBLE).named("amount")
149+
.named("sale");
150+
151+
startTime = System.currentTimeMillis();
152+
count = 0;
153+
// Note: withProjection is not available in this version, using configuration instead
154+
org.apache.hadoop.conf.Configuration conf = new org.apache.hadoop.conf.Configuration();
155+
conf.set("parquet.read.schema", projection.toString());
156+
157+
try (ParquetReader<Group> reader = ParquetReader.builder(new GroupReadSupport(), file)
158+
.withConf(conf)
159+
.build()) {
160+
161+
Group group;
162+
while ((group = reader.read()) != null) {
163+
count++;
164+
}
165+
}
166+
long projectionTime = System.currentTimeMillis() - startTime;
167+
System.out.printf("Projection: Read %d records in %dms (%.1fx faster)%n",
168+
count, projectionTime, (double) defaultTime / projectionTime);
169+
}
170+
}

0 commit comments

Comments
 (0)