Skip to content

Commit

Permalink
Generated index API: a single HashIndex class for the API, all indexe…
Browse files Browse the repository at this point in the history
…s register as RefreshListeners, and all indexes ensure that updates do not happen during initial indexing
  • Loading branch information
dkoszewnik committed May 20, 2017
1 parent e28c9dc commit 2d9a131
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,28 @@
*/
package com.netflix.hollow.api.codegen;

import com.netflix.hollow.api.codegen.indexes.HollowHashIndexGenerator;

import com.netflix.hollow.core.schema.HollowSchema.SchemaType;
import com.netflix.hollow.api.codegen.indexes.HollowPrimaryKeyIndexGenerator;
import com.netflix.hollow.api.custom.HollowAPI;
import com.netflix.hollow.core.schema.HollowListSchema;
import com.netflix.hollow.core.schema.HollowMapSchema;
import com.netflix.hollow.core.schema.HollowObjectSchema;
import com.netflix.hollow.core.schema.HollowSchema;
import com.netflix.hollow.core.schema.HollowSetSchema;
import com.netflix.hollow.core.HollowDataset;
import com.netflix.hollow.api.codegen.api.TypeAPIListJavaGenerator;
import com.netflix.hollow.api.codegen.api.TypeAPIMapJavaGenerator;
import com.netflix.hollow.api.codegen.api.TypeAPIObjectJavaGenerator;
import com.netflix.hollow.api.codegen.api.TypeAPISetJavaGenerator;
import com.netflix.hollow.api.codegen.delegate.HollowObjectDelegateCachedImplGenerator;
import com.netflix.hollow.api.codegen.delegate.HollowObjectDelegateInterfaceGenerator;
import com.netflix.hollow.api.codegen.delegate.HollowObjectDelegateLookupImplGenerator;
import com.netflix.hollow.api.codegen.indexes.HollowHashIndexGenerator;
import com.netflix.hollow.api.codegen.indexes.HollowPrimaryKeyIndexGenerator;
import com.netflix.hollow.api.codegen.objects.HollowFactoryJavaGenerator;
import com.netflix.hollow.api.codegen.objects.HollowListJavaGenerator;
import com.netflix.hollow.api.codegen.objects.HollowMapJavaGenerator;
import com.netflix.hollow.api.codegen.objects.HollowObjectJavaGenerator;
import com.netflix.hollow.api.codegen.objects.HollowSetJavaGenerator;
import com.netflix.hollow.api.custom.HollowAPI;
import com.netflix.hollow.core.HollowDataset;
import com.netflix.hollow.core.schema.HollowListSchema;
import com.netflix.hollow.core.schema.HollowMapSchema;
import com.netflix.hollow.core.schema.HollowObjectSchema;
import com.netflix.hollow.core.schema.HollowSchema;
import com.netflix.hollow.core.schema.HollowSchema.SchemaType;
import com.netflix.hollow.core.schema.HollowSetSchema;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
Expand Down Expand Up @@ -127,9 +126,11 @@ public void generateFiles(File directory) throws IOException {

HollowAPIClassJavaGenerator apiClassGenerator = new HollowAPIClassJavaGenerator(packageName, apiClassname, dataset, parameterizeClassNames, classPostfix);
HollowAPIFactoryJavaGenerator apiFactoryGenerator = new HollowAPIFactoryJavaGenerator(packageName, apiClassname);
HollowHashIndexGenerator hashIndexGenerator = new HollowHashIndexGenerator(packageName, apiClassname, classPostfix, dataset);

generateFile(directory, apiClassGenerator);
generateFile(directory, apiFactoryGenerator);
generateFile(directory, hashIndexGenerator);

generateFilesForHollowSchemas(directory);
}
Expand All @@ -145,7 +146,6 @@ private void generateFilesForHollowSchemas(File directory) throws IOException {
generateFile(directory, new HollowObjectDelegateCachedImplGenerator(packageName, (HollowObjectSchema)schema));
generateFile(directory, new HollowObjectDelegateLookupImplGenerator(packageName, (HollowObjectSchema)schema));
generateFile(directory, new HollowPrimaryKeyIndexGenerator(packageName, apiClassname, classPostfix, (HollowObjectSchema)schema));
generateFile(directory, new HollowHashIndexGenerator(packageName, apiClassname, classPostfix, (HollowObjectSchema)schema));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,22 @@
package com.netflix.hollow.api.codegen.indexes;

import static com.netflix.hollow.api.codegen.HollowCodeGenerationUtils.hollowImplClassname;
import static com.netflix.hollow.api.codegen.HollowCodeGenerationUtils.substituteInvalidChars;

import com.netflix.hollow.api.codegen.HollowAPIGenerator;
import com.netflix.hollow.api.codegen.HollowJavaFileGenerator;
import com.netflix.hollow.api.consumer.HollowConsumer;
import com.netflix.hollow.api.custom.HollowAPI;
import com.netflix.hollow.core.HollowDataset;
import com.netflix.hollow.core.index.HollowHashIndex;
import com.netflix.hollow.core.index.HollowHashIndexResult;
import com.netflix.hollow.core.read.engine.HollowReadStateEngine;
import com.netflix.hollow.core.read.iterator.HollowOrdinalIterator;
import com.netflix.hollow.core.schema.HollowObjectSchema;
import com.netflix.hollow.core.schema.HollowSchema;
import com.netflix.hollow.core.schema.HollowSchemaSorter;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
* This class contains template logic for generating a {@link HollowAPI} implementation. Not intended for external consumption.
Expand All @@ -43,14 +47,14 @@ public class HollowHashIndexGenerator implements HollowJavaFileGenerator {
private final String classname;
private final String apiClassname;
private final String classPostfix;
private final HollowObjectSchema schema;
private final HollowDataset dataset;

public HollowHashIndexGenerator(String packageName, String apiClassname, String classPostfix, HollowObjectSchema schema) {
this.classname = schema.getName() + "HashIndex";
public HollowHashIndexGenerator(String packageName, String apiClassname, String classPostfix, HollowDataset dataset) {
this.classname = apiClassname + "HashIndex";
this.apiClassname = apiClassname;
this.packageName = packageName;
this.classPostfix = classPostfix;
this.schema = schema;
this.dataset = dataset;
}

@Override
Expand All @@ -60,6 +64,8 @@ public String getClassName() {

@Override
public String generate() {
List<HollowSchema> schemaList = HollowSchemaSorter.dependencyOrderedSchemaList(dataset);

StringBuilder builder = new StringBuilder();

builder.append("package " + packageName + ";\n\n");
Expand All @@ -78,44 +84,52 @@ public String generate() {

builder.append(" private HollowHashIndex idx;\n");
builder.append(" private " + apiClassname + " api;\n");
builder.append(" private final String queryType;");
builder.append(" private final String selectFieldPath;\n");
builder.append(" private final String matchFieldPaths[];\n\n");

builder.append(" public " + classname + "(HollowConsumer consumer, String selectFieldPath, String... matchFieldPaths) {\n");
builder.append(" public " + classname + "(HollowConsumer consumer, String queryType, String selectFieldPath, String... matchFieldPaths) {\n");
builder.append(" this.queryType = queryType;");
builder.append(" this.selectFieldPath = selectFieldPath;\n");
builder.append(" this.matchFieldPaths = matchFieldPaths;\n");
builder.append(" this.idx = new HollowHashIndex(consumer.getStateEngine(), \"" + schema.getName() + "\", selectFieldPath, matchFieldPaths);\n");
builder.append(" consumer.getRefreshLock().lock();\n");
builder.append(" try {\n");
builder.append(" this.api = (" + apiClassname + ")consumer.getAPI();\n");
builder.append(" this.idx = new HollowHashIndex(consumer.getStateEngine(), queryType, selectFieldPath, matchFieldPaths);\n");
builder.append(" consumer.addRefreshListener(this);\n");
builder.append(" } catch(ClassCastException cce) {\n");
builder.append(" throw new ClassCastException(\"The HollowConsumer provided was not created with the " + apiClassname + " generated API class.\");\n");
builder.append(" } finally {\n");
builder.append(" consumer.getRefreshLock().unlock();\n");
builder.append(" }\n");
builder.append(" }\n\n");

builder.append(" public Iterable<" + hollowImplClassname(schema.getName(), classPostfix) + "> findMatches(Object... keys) {\n");
builder.append(" HollowHashIndexResult matches = idx.findMatches(keys);\n");
builder.append(" if(matches == null)\n");
builder.append(" return Collections.emptySet();\n\n");
builder.append(" final HollowOrdinalIterator iter = matches.iterator();\n\n");
builder.append(" return new Iterable<" + hollowImplClassname(schema.getName(), classPostfix) + ">() {\n");
builder.append(" public Iterator<" + hollowImplClassname(schema.getName(), classPostfix) + "> iterator() {\n");
builder.append(" return new Iterator<" + hollowImplClassname(schema.getName(), classPostfix) + ">() {\n\n");
builder.append(" private int next = iter.next();\n\n");
builder.append(" public boolean hasNext() {\n");
builder.append(" return next != HollowOrdinalIterator.NO_MORE_ORDINALS;\n");
builder.append(" }\n\n");
builder.append(" public " + hollowImplClassname(schema.getName(), classPostfix) + " next() {\n");
builder.append(" " + hollowImplClassname(schema.getName(), classPostfix) + " obj = api.get" + hollowImplClassname(schema.getName(), classPostfix) + "(next);\n");
builder.append(" next = iter.next();\n");
builder.append(" return obj;\n");
builder.append(" }\n\n");
builder.append(" public void remove() {\n");
builder.append(" throw new UnsupportedOperationException();\n");
builder.append(" }\n");
builder.append(" };\n");
builder.append(" }\n");
builder.append(" };\n");
builder.append(" }\n\n");
for(HollowSchema schema : schemaList) {
builder.append(" public Iterable<" + hollowImplClassname(schema.getName(), classPostfix) + "> find" + substituteInvalidChars(schema.getName()) + "Matches(Object... keys) {\n");
builder.append(" HollowHashIndexResult matches = idx.findMatches(keys);\n");
builder.append(" if(matches == null)\n");
builder.append(" return Collections.emptySet();\n\n");
builder.append(" final HollowOrdinalIterator iter = matches.iterator();\n\n");
builder.append(" return new Iterable<" + hollowImplClassname(schema.getName(), classPostfix) + ">() {\n");
builder.append(" public Iterator<" + hollowImplClassname(schema.getName(), classPostfix) + "> iterator() {\n");
builder.append(" return new Iterator<" + hollowImplClassname(schema.getName(), classPostfix) + ">() {\n\n");
builder.append(" private int next = iter.next();\n\n");
builder.append(" public boolean hasNext() {\n");
builder.append(" return next != HollowOrdinalIterator.NO_MORE_ORDINALS;\n");
builder.append(" }\n\n");
builder.append(" public " + hollowImplClassname(schema.getName(), classPostfix) + " next() {\n");
builder.append(" " + hollowImplClassname(schema.getName(), classPostfix) + " obj = api.get" + hollowImplClassname(schema.getName(), classPostfix) + "(next);\n");
builder.append(" next = iter.next();\n");
builder.append(" return obj;\n");
builder.append(" }\n\n");
builder.append(" public void remove() {\n");
builder.append(" throw new UnsupportedOperationException();\n");
builder.append(" }\n");
builder.append(" };\n");
builder.append(" }\n");
builder.append(" };\n");
builder.append(" }\n\n");
}

builder.append(" @Override public void deltaUpdateOccurred(HollowAPI api, HollowReadStateEngine stateEngine, long version) throws Exception {\n");
builder.append(" reindex(stateEngine, api);\n");
Expand All @@ -126,7 +140,7 @@ public String generate() {
builder.append(" }\n\n");

builder.append(" private void reindex(HollowReadStateEngine stateEngine, HollowAPI api) {\n");
builder.append(" this.idx = new HollowHashIndex(stateEngine, \"" + schema.getName() + "\", selectFieldPath, matchFieldPaths);\n");
builder.append(" this.idx = new HollowHashIndex(stateEngine, queryType, selectFieldPath, matchFieldPaths);\n");
builder.append(" this.api = (" + apiClassname + ") api;\n");
builder.append(" }\n\n");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,16 @@ public String generate() {
builder.append(" }\n\n");

builder.append(" public " + classname + "(HollowConsumer consumer, String... fieldPaths) {\n");
builder.append(" this.idx = new HollowPrimaryKeyIndex(consumer.getStateEngine(), \"" + schema.getName() + "\", fieldPaths);\n");
builder.append(" idx.listenForDeltaUpdates();\n");
builder.append(" consumer.getRefreshLock().lock();\n");
builder.append(" try {\n");
builder.append(" this.api = (" + apiClassname + ")consumer.getAPI();\n");
builder.append(" this.idx = new HollowPrimaryKeyIndex(consumer.getStateEngine(), \"" + schema.getName() + "\", fieldPaths);\n");
builder.append(" idx.listenForDeltaUpdates();\n");
builder.append(" consumer.addRefreshListener(this);\n");
builder.append(" } catch(ClassCastException cce) {\n");
builder.append(" throw new ClassCastException(\"The HollowConsumer provided was not created with the " + apiClassname + " generated API class.\");\n");
builder.append(" } finally {\n");
builder.append(" consumer.getRefreshLock().unlock();\n");
builder.append(" }\n");
builder.append(" }\n\n");

Expand Down

0 comments on commit 2d9a131

Please sign in to comment.