-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Always return PrimitiveFloatList, even when cold
The PrimitiveFloatList is an API which users should expect to rely on, so it is wrong to degrade to the more constrained List<Float> API while Fast-Avro is still cold. This commit introduces several changes to make the extended API reliably present whenever using Fast-Avro, regardless of being cold or warm. - Changed PrimitiveFloatList to an interface, in a new package called: com.linkedin.avro.api; since the package name migration makes this an incompatible change, it would be desirable for the next release to not increment only the patch version. Having a proper package name for API extension should make things cleaner in the future as we add other optimized APIs (e.g. PR #45). - Renamed the old class to ByteBufferBackedPrimitiveFloatList, and made it implement the new interface. - Added new several new classes to ensure that the PrimitiveFloatList is always returned even when Fast-Avro falls back to vanilla Avro: - ColdPrimitiveFloatList which is a naive implementation that simply implements the new API by delegating to the regular Avro functions. This does not provide any GC benefits, but at least maintains the API. - ColdGenericDatumReader and ColdSpecificDatumReader which extend the GenericDatumReader and SpecificDatumReader classes, respectively, from vanilla Avro. - ColdDatumReaderMixIn which provides a utility function to minimize repeated code between the two DatumReader functions. - Significantly refactored the FastGenericDeserializerGeneratorTest so that it tests three permutations: vanilla, cold fast and warm fast. As part of doing this, several test short-comings were discovered and fixed. In particular, the decodeRecordSlow function had some flipped parameters which led to test failures on vanilla Avro, and those test failures were hidden by the fact that some tests ignored the provided permutation param and systematically tested only Fast-Avro.
- Loading branch information
Showing
10 changed files
with
321 additions
and
181 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
avro-fastserde/src/main/java/com/linkedin/avro/api/PrimitiveFloatList.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.linkedin.avro.api; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* A {@link List} implementation with additional functions to prevent boxing. | ||
*/ | ||
public interface PrimitiveFloatList extends List<Float> { | ||
/** | ||
* @param index index of the element to return | ||
* @return the element at the specified position in this list | ||
*/ | ||
float getPrimitive(int index); | ||
|
||
/** | ||
* @param e element whose presence in this collection is to be ensured | ||
* @return <tt>true</tt> if this collection changed as a result of the call | ||
*/ | ||
boolean addPrimitive(float e); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
...fastserde/src/main/java/com/linkedin/avro/fastserde/coldstart/ColdPrimitiveFloatList.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.linkedin.avro.fastserde.coldstart; | ||
|
||
import com.linkedin.avro.api.PrimitiveFloatList; | ||
import org.apache.avro.Schema; | ||
import org.apache.avro.generic.GenericData; | ||
|
||
/** | ||
* A {@link PrimitiveFloatList} implementation which is equivalent in all respect to the vanilla Avro | ||
* implementation, both in terms of functionality and (lack of) performance. It provides the primitive | ||
* API that the interface requires, but actually just returns an unboxed Float Object, thus providing | ||
* no GC benefit. This should be possible to improve upon in the future, however. | ||
* | ||
* The main motivation for this class is merely to provide a guarantee that the extended API is always | ||
* available, even when Fast-Avro isn't warmed up yet. | ||
*/ | ||
public class ColdPrimitiveFloatList extends GenericData.Array<Float> implements PrimitiveFloatList { | ||
private static final Schema SCHEMA = Schema.createArray(Schema.create(Schema.Type.FLOAT)); | ||
public ColdPrimitiveFloatList(int capacity) { | ||
super(capacity, SCHEMA); | ||
} | ||
|
||
@Override | ||
public float getPrimitive(int index) { | ||
return get(index); | ||
} | ||
|
||
@Override | ||
public boolean addPrimitive(float o) { | ||
return add(o); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
avro-fastserde/src/main/java/org/apache/avro/generic/ColdDatumReaderMixIn.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package org.apache.avro.generic; | ||
|
||
import com.linkedin.avro.fastserde.coldstart.ColdPrimitiveFloatList; | ||
import java.util.Collection; | ||
import org.apache.avro.Schema; | ||
|
||
|
||
/** | ||
* An interface with default implementation in order to defeat the lack of multiple inheritance. | ||
*/ | ||
public interface ColdDatumReaderMixIn { | ||
default Object newArray(Object old, int size, Schema schema, NewArrayFunction fallBackFunction) { | ||
switch (schema.getElementType().getType()) { | ||
case FLOAT: | ||
if (null == old || !(old instanceof ColdPrimitiveFloatList)) { | ||
return new ColdPrimitiveFloatList(size); | ||
} | ||
((Collection) old).clear(); | ||
return old; | ||
// TODO: Add more cases when we support more primitive array types | ||
default: | ||
return fallBackFunction.newArray(old, size, schema); | ||
} | ||
} | ||
|
||
interface NewArrayFunction { | ||
Object newArray(Object old, int size, Schema schema); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
avro-fastserde/src/main/java/org/apache/avro/generic/ColdGenericDatumReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.apache.avro.generic; | ||
|
||
import org.apache.avro.Schema; | ||
|
||
|
||
/** | ||
* A light-weight extension of {@link GenericDatumReader} which merely ensures that the types of the | ||
* extended API are always returned. | ||
* | ||
* This class needs to be in the org.apache.avro.generic package in order to access protected methods. | ||
*/ | ||
public class ColdGenericDatumReader<T> extends GenericDatumReader<T> implements ColdDatumReaderMixIn { | ||
public ColdGenericDatumReader(Schema writerSchema, Schema readerSchema) { | ||
super(writerSchema, readerSchema); | ||
} | ||
|
||
@Override | ||
protected Object newArray(Object old, int size, Schema schema) { | ||
return newArray(old, size, schema, super::newArray); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
avro-fastserde/src/main/java/org/apache/avro/generic/ColdSpecificDatumReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package org.apache.avro.generic; | ||
|
||
import org.apache.avro.Schema; | ||
import org.apache.avro.specific.SpecificDatumReader; | ||
|
||
|
||
/** | ||
* A light-weight extension of {@link SpecificDatumReader} which merely ensures that the types of | ||
* the extended API are always returned. | ||
* | ||
* This class needs to be in the org.apache.avro.generic package in order to access protected methods. | ||
*/ | ||
public class ColdSpecificDatumReader<T> extends SpecificDatumReader<T> implements ColdDatumReaderMixIn { | ||
public ColdSpecificDatumReader(Schema writerSchema, Schema readerSchema) { | ||
super(writerSchema, readerSchema); | ||
} | ||
|
||
@Override | ||
protected Object newArray(Object old, int size, Schema schema) { | ||
return newArray(old, size, schema, super::newArray); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.