-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PARTIAL PROJECTIONS ON CACHED DATA WITH INTERFACES LETS GO
- Loading branch information
Showing
13 changed files
with
353 additions
and
89 deletions.
There are no files selected for viewing
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
82 changes: 82 additions & 0 deletions
82
inset-core/src/main/java/slatepowered/inset/internal/ProjectionInterface.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,82 @@ | ||
package slatepowered.inset.internal; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import slatepowered.inset.operation.Projection; | ||
import slatepowered.inset.util.Reflections; | ||
import slatepowered.veru.reflect.ReflectUtil; | ||
|
||
import java.lang.reflect.Method; | ||
import java.lang.reflect.Proxy; | ||
import java.lang.reflect.Type; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.BiFunction; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
|
||
@RequiredArgsConstructor | ||
@Getter | ||
public class ProjectionInterface implements ProjectionType { | ||
|
||
/** | ||
* The interface class. | ||
*/ | ||
protected final Class<?> klass; | ||
|
||
/** | ||
* The method representing the key field. | ||
*/ | ||
protected final Method keyMethod; | ||
|
||
/** | ||
* The other data field methods. | ||
*/ | ||
protected final List<Method> fieldMethods; | ||
|
||
/** | ||
* Create a new proxy for this interface with the given parameters. | ||
* | ||
* @return The proxy instance. | ||
*/ | ||
public Object createProxy(Supplier<Object> keySupplier, | ||
BiFunction<String, Type, Object> fieldGetter) { | ||
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[] { klass }, (proxy, method, args) -> { | ||
if (method.isDefault()) { | ||
return ReflectUtil.invokeDefault(proxy, method, args); | ||
} | ||
|
||
if (method.equals(keyMethod)) { | ||
return keySupplier.get(); | ||
} | ||
|
||
if (method.equals(Reflections.METHOD_OBJECT_EQUALS)) { | ||
return false; // todo | ||
} else if (method.equals(Reflections.METHOD_OBJECT_TOSTRING)) { | ||
return "partial projection of key " + keySupplier.get().toString(); | ||
} else if (method.equals(Reflections.METHOD_OBJECT_HASHCODE)) { | ||
return keySupplier.get().hashCode(); | ||
} | ||
|
||
return fieldGetter.apply(method.getName(), method.getGenericReturnType()); | ||
}); | ||
} | ||
|
||
@Override | ||
public Projection createExclusiveProjection(String primaryKeyNameOverride) { | ||
List<String> fields = new ArrayList<>(); | ||
|
||
// add applicable data fields | ||
for (Method method : fieldMethods) { | ||
fields.add(method.getName()); | ||
} | ||
|
||
// add primary key field | ||
if (primaryKeyNameOverride == null) | ||
primaryKeyNameOverride = keyMethod.getName(); | ||
fields.add(primaryKeyNameOverride); | ||
|
||
return Projection.include(fields); | ||
} | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
inset-core/src/main/java/slatepowered/inset/internal/ProjectionType.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,19 @@ | ||
package slatepowered.inset.internal; | ||
|
||
import slatepowered.inset.operation.Projection; | ||
|
||
/** | ||
* Represents a type which can be used as a projection. | ||
*/ | ||
public interface ProjectionType { | ||
|
||
/** | ||
* Create a new projection which only includes the fields | ||
* applicable to this data. | ||
* | ||
* @param primaryKeyNameOverride The primary key field name override. | ||
* @return The projection. | ||
*/ | ||
Projection createExclusiveProjection(String primaryKeyNameOverride); | ||
|
||
} |
85 changes: 85 additions & 0 deletions
85
inset-core/src/main/java/slatepowered/inset/internal/ProjectionTypes.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,85 @@ | ||
package slatepowered.inset.internal; | ||
|
||
import slatepowered.inset.codec.DataCodec; | ||
import slatepowered.inset.datastore.Datastore; | ||
import slatepowered.inset.operation.Projection; | ||
import slatepowered.inset.reflective.Key; | ||
|
||
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
|
||
/** | ||
* Support with projection-defining interfaces. | ||
*/ | ||
public final class ProjectionTypes { | ||
|
||
/** | ||
* All compiled projection interfaces. | ||
*/ | ||
private static final Map<Class<?>, ProjectionInterface> compiledInterfaces = new ConcurrentHashMap<>(); | ||
|
||
/** | ||
* Get or compile the projection data for the given interface. | ||
* | ||
* @param klass The interface class. | ||
* @return The interface. | ||
*/ | ||
public static ProjectionInterface compileProjectionInterface(Class<?> klass) { | ||
ProjectionInterface projectionInterface = compiledInterfaces.get(klass); | ||
if (projectionInterface != null) { | ||
return projectionInterface; | ||
} | ||
|
||
if (!klass.isInterface()) { | ||
return null; | ||
} | ||
|
||
Method[] methods = klass.getMethods(); | ||
List<Method> fieldMethods = new ArrayList<>(); | ||
Method keyMethod = null; | ||
for (Method method : methods) { | ||
// check for primary key method | ||
if (method.isAnnotationPresent(Key.class)) { | ||
keyMethod = method; | ||
continue; | ||
} | ||
|
||
fieldMethods.add(method); | ||
} | ||
|
||
compiledInterfaces.put(klass, projectionInterface = new ProjectionInterface(klass, keyMethod, fieldMethods)); | ||
return projectionInterface; | ||
} | ||
|
||
/** | ||
* Get or compile a {@link ProjectionType} for the given class/type in the context | ||
* of the given datastore. | ||
* | ||
* @param klass The class. | ||
* @param datastore The datastore. | ||
* @return The {@link ProjectionType} instance. | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
public static <K, T, V> ProjectionType getProjectionType(Class<V> klass, Datastore<K, T> datastore) { | ||
ProjectionType projectionType = null; | ||
|
||
// check for projection interface | ||
if (klass.isInterface()) { | ||
projectionType = compileProjectionInterface(klass); | ||
} | ||
|
||
// check for class | ||
else { | ||
projectionType = datastore.getCodecRegistry().getCodec(klass).expect(DataCodec.class); | ||
} | ||
|
||
if (projectionType != null) | ||
return projectionType; | ||
throw new UnsupportedOperationException("Unsupported type for projection of potentially partial data: " + klass); | ||
} | ||
|
||
} |
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.