Skip to content

Commit 899df1d

Browse files
feat(java): introduce new 'compact' row encoding
compact encoding will store fixed sized fields inline, relaxes alignment considerations to preserve alignment where possible but using space more effectively
1 parent 0416413 commit 899df1d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2970
-567
lines changed

java/fory-core/src/main/java/org/apache/fory/builder/CodecBuilder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ public CodecBuilder(CodegenContext ctx, TypeRef<?> beanType) {
117117
// For example user class named as `Date`/`List`/`MemoryBuffer`
118118
}
119119

120+
public abstract String codecClassName(Class<?> cls);
121+
120122
/** Generate codec class code. */
121123
public abstract String genCode();
122124

java/fory-core/src/main/java/org/apache/fory/memory/MemoryBuffer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
* <li>additional binary compare, swap, and copy methods.
4141
* <li>little-endian access.
4242
* <li>independent read/write index.
43-
* <li>variant int/long encoding.
43+
* <li>varint int/long encoding.
4444
* <li>aligned int/long encoding.
4545
* </ul>
4646
*
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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.fory.format.encoder;
21+
22+
import static org.apache.fory.type.TypeUtils.getRawType;
23+
24+
import java.lang.reflect.Constructor;
25+
import java.util.Collection;
26+
import java.util.HashSet;
27+
import java.util.Set;
28+
import java.util.function.Function;
29+
import java.util.function.Supplier;
30+
import org.apache.arrow.vector.types.pojo.Field;
31+
import org.apache.arrow.vector.types.pojo.Schema;
32+
import org.apache.fory.format.row.binary.writer.BinaryArrayWriter;
33+
import org.apache.fory.format.type.DataTypes;
34+
import org.apache.fory.format.type.TypeInference;
35+
import org.apache.fory.reflect.TypeRef;
36+
import org.apache.fory.type.TypeUtils;
37+
38+
public class ArrayCodecBuilder<C extends Collection<?>>
39+
extends BaseCodecBuilder<ArrayCodecBuilder<C>> {
40+
41+
private final TypeRef<C> collectionType;
42+
43+
ArrayCodecBuilder(final TypeRef<C> collectionType) {
44+
super(TypeInference.inferSchema(collectionType, false));
45+
this.collectionType = collectionType;
46+
}
47+
48+
public Supplier<ArrayEncoder<C>> buildForArray() {
49+
final Function<BinaryArrayWriter, ArrayEncoder<C>> arrayEncoderFactory =
50+
buildForArrayWithCustomWriter();
51+
final Schema collectionSchema = TypeInference.inferSchema(collectionType, false);
52+
final Field field = DataTypes.fieldOfSchema(collectionSchema, 0);
53+
return new Supplier<ArrayEncoder<C>>() {
54+
@Override
55+
public ArrayEncoder<C> get() {
56+
final BinaryArrayWriter writer = codecFactory.newArrayWriter(field);
57+
return arrayEncoderFactory.apply(writer);
58+
}
59+
};
60+
}
61+
62+
public Function<BinaryArrayWriter, ArrayEncoder<C>> buildForArrayWithCustomWriter() {
63+
loadArrayInnerCodecs(collectionType);
64+
final Function<BinaryArrayWriter, GeneratedArrayEncoder> arrayEncoderFactory =
65+
arrayEncoderFactory(collectionType);
66+
return new Function<BinaryArrayWriter, ArrayEncoder<C>>() {
67+
@Override
68+
public ArrayEncoder<C> apply(final BinaryArrayWriter writer) {
69+
return new BeanArrayEncoder<>(writer, writer.getField(), arrayEncoderFactory.apply(writer));
70+
}
71+
};
72+
}
73+
74+
private void loadArrayInnerCodecs(final TypeRef<?> collectionType) {
75+
final Set<TypeRef<?>> set = new HashSet<>();
76+
Encoders.findBeanToken(collectionType, set);
77+
if (set.isEmpty()) {
78+
throw new IllegalArgumentException("can not find bean class.");
79+
}
80+
81+
TypeRef<?> typeRef = null;
82+
for (final TypeRef<?> tt : set) {
83+
typeRef = set.iterator().next();
84+
Encoders.loadOrGenRowCodecClass(getRawType(tt), codecFactory);
85+
}
86+
}
87+
88+
Function<BinaryArrayWriter, GeneratedArrayEncoder> arrayEncoderFactory(
89+
final TypeRef<? extends Collection<?>> collectionType) {
90+
final TypeRef<?> elementType = TypeUtils.getElementType(collectionType);
91+
final Class<?> arrayCodecClass =
92+
Encoders.loadOrGenArrayCodecClass(collectionType, elementType, codecFactory);
93+
94+
Constructor<? extends GeneratedArrayEncoder> constructor;
95+
try {
96+
constructor =
97+
arrayCodecClass.asSubclass(GeneratedArrayEncoder.class).getConstructor(Object[].class);
98+
} catch (final NoSuchMethodException e) {
99+
throw new EncoderException(
100+
"Failed to construct array codec for "
101+
+ collectionType
102+
+ " with element class "
103+
+ elementType,
104+
e);
105+
}
106+
return new Function<BinaryArrayWriter, GeneratedArrayEncoder>() {
107+
@Override
108+
public GeneratedArrayEncoder apply(final BinaryArrayWriter writer) {
109+
final Field field = writer.getField();
110+
final Object references = new Object[] {field, writer, fory};
111+
try {
112+
return constructor.newInstance(references);
113+
} catch (final ReflectiveOperationException e) {
114+
throw new EncoderException(
115+
"Failed to construct array codec for "
116+
+ collectionType
117+
+ " with element class "
118+
+ elementType,
119+
e);
120+
}
121+
}
122+
};
123+
}
124+
}

java/fory-format/src/main/java/org/apache/fory/format/encoder/ArrayEncoderBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public String genCode() {
136136
@Override
137137
public Expression buildEncodeExpression() {
138138
Expression.Reference arrayWriter =
139-
new Expression.Reference(ROOT_ARRAY_WRITER_NAME, arrayWriterTypeToken, false);
139+
new Expression.Reference(ROOT_ARRAY_WRITER_NAME, arrayWriterType(), false);
140140
Expression.ListExpression expressions = new Expression.ListExpression();
141141

142142
Expression.Reference inputObject =
@@ -148,7 +148,7 @@ public Expression buildEncodeExpression() {
148148

149149
Expression.Reference fieldExpr = new Expression.Reference(FIELD_NAME, ARROW_FIELD_TYPE, false);
150150
Expression listExpression =
151-
serializeForArrayByWriter(array, arrayWriter, arrayToken, fieldExpr);
151+
serializeForArrayByWriter(array, arrayWriter, arrayToken, null, fieldExpr);
152152

153153
expressions.add(listExpression);
154154

0 commit comments

Comments
 (0)