/** * Dependency types come before dependent types * * @param dataset the data set * @return the dependent schema */ public static List<HollowSchema> dependencyOrderedSchemaList(HollowDataset dataset) { return dependencyOrderedSchemaList(dataset.getSchemas()); }
private List<PrimaryKey> sortPrimaryKeys(List<PrimaryKey> primaryKeys) { final List<HollowSchema> dependencyOrderedSchemas = HollowSchemaSorter.dependencyOrderedSchemaList(output.getSchemas()); Collections.sort(primaryKeys, new Comparator<PrimaryKey>() { public int compare(PrimaryKey o1, PrimaryKey o2) { return schemaDependencyIdx(o1) - schemaDependencyIdx(o2); } private int schemaDependencyIdx(PrimaryKey key) { for(int i=0;i<dependencyOrderedSchemas.size();i++) { if(dependencyOrderedSchemas.get(i).getName().equals(key.getType())) return i; } throw new IllegalArgumentException("Primary key defined for non-existent type: " + key.getType()); } }); return primaryKeys; }
/** * Augment the given selection by adding the references, and the <i>transitive</i> references, of our selection. * @param stateEngine the state engine * @param matches the map to which matches are placed */ public static void addTransitiveMatches(HollowReadStateEngine stateEngine, Map<String, BitSet> matches) { List<HollowSchema> schemaList = HollowSchemaSorter.dependencyOrderedSchemaList(stateEngine); Collections.reverse(schemaList); for(HollowSchema schema : schemaList) { BitSet currentMatches = matches.get(schema.getName()); if(currentMatches != null) { addTransitiveMatches(stateEngine, schema.getName(), matches); } } }
@Override public String generate() { List<HollowSchema> schemaList = HollowSchemaSorter.dependencyOrderedSchemaList(dataset);
/** * Create a delta patcher which will patch between the states contained in the two state engines. * * @param from The earlier state * @param to The later state. */ public HollowStateDeltaPatcher(HollowReadStateEngine from, HollowReadStateEngine to) { this.from = from; this.to = to; this.schemas = HollowSchemaSorter.dependencyOrderedSchemaList(getCommonSchemas(from, to)); this.writeEngine = HollowWriteStateCreator.createWithSchemas(schemas); this.changedOrdinalsBetweenStates = discoverChangedOrdinalsBetweenStates(); }
/** * Remove any records from the given selection which are referenced by other records not in the selection. * @param stateEngine the state engine * @param matches the matches */ public static void removeReferencedOutsideClosure(HollowReadStateEngine stateEngine, Map<String, BitSet> matches) { List<HollowSchema> orderedSchemas = HollowSchemaSorter.dependencyOrderedSchemaList(stateEngine); Collections.reverse(orderedSchemas); for(HollowSchema referencedSchema : orderedSchemas) { if(matches.containsKey(referencedSchema.getName())) { for(HollowSchema referencerSchema : orderedSchemas) { if(referencerSchema == referencedSchema) break; if(matches.containsKey(referencedSchema.getName()) && matches.get(referencedSchema.getName()).cardinality() > 0) traverseReferencesOutsideClosure(stateEngine, referencerSchema.getName(), referencedSchema.getName(), matches, REMOVE_REFERENCED_OUTSIDE_CLOSURE); } } } }
/** * Augment the given selection with any records outside the selection which reference * (or transitively reference) any records in the selection. * @param stateEngine the state engine * @param matches the matches */ public static void addReferencingOutsideClosure(HollowReadStateEngine stateEngine, Map<String, BitSet> matches) { List<HollowSchema> orderedSchemas = HollowSchemaSorter.dependencyOrderedSchemaList(stateEngine); for(HollowSchema referencerSchema : orderedSchemas) { for(HollowSchema referencedSchema : orderedSchemas) { if(referencedSchema == referencerSchema) break; if(matches.containsKey(referencedSchema.getName()) && matches.get(referencedSchema.getName()).cardinality() > 0) traverseReferencesOutsideClosure(stateEngine, referencerSchema.getName(), referencedSchema.getName(), matches, ADD_REFERENCING_OUTSIDE_CLOSURE); } } }
/** * Find candidate types for compaction. No two types in the returned set will have a dependency relationship, either * directly or transitively. */ private Set<String> findCompactionTargets() { List<HollowSchema> schemas = HollowSchemaSorter.dependencyOrderedSchemaList(readEngine.getSchemas()); Set<String> typesToCompact = new HashSet<String>(); for(HollowSchema schema : schemas) { if(isCompactionCandidate(schema.getName())) { if(!candidateIsDependentOnAnyTargetedType(schema.getName(), typesToCompact)) typesToCompact.add(schema.getName()); } } return typesToCompact; }
@Override public String generate() { List<HollowSchema> schemaList = HollowSchemaSorter.dependencyOrderedSchemaList(dataset);
@Test public void sortsSchemasEvenIfDependencyTypesNotPresent() throws IOException { String schemasText = "TypeA { TypeB b; }" + "TypeB { TypeC c; }"; List<HollowSchema> schemas = HollowSchemaParser.parseCollectionOfSchemas(schemasText); List<HollowSchema> sortedSchemas = HollowSchemaSorter.dependencyOrderedSchemaList(schemas); Assert.assertEquals(2, sortedSchemas.size()); Assert.assertEquals("TypeB", sortedSchemas.get(0).getName()); Assert.assertEquals("TypeA", sortedSchemas.get(1).getName()); }
for(HollowSchema schema : HollowSchemaSorter.dependencyOrderedSchemaList(writeEngine.getSchemas())) { if(!compactionTargets.contains(schema.getName())) { HollowTypeWriteState writeState = writeEngine.getTypeState(schema.getName());
@Test public void schemasAreSortedBasedOnDependencies() throws IOException { String schemasText = "TypeB {" + " ListOfString str;" + "}" + "" + "String {" + " string value;" + "}" + "" + "ListOfString List<String>;" + "" + "TypeA {" + " TypeB b;" + " String str;" + "}"; List<HollowSchema> schemas = HollowSchemaParser.parseCollectionOfSchemas(schemasText); List<HollowSchema> sortedSchemas = HollowSchemaSorter.dependencyOrderedSchemaList(schemas); Assert.assertEquals(4, sortedSchemas.size()); Assert.assertEquals("String", sortedSchemas.get(0).getName()); Assert.assertEquals("ListOfString", sortedSchemas.get(1).getName()); Assert.assertEquals("TypeB", sortedSchemas.get(2).getName()); Assert.assertEquals("TypeA", sortedSchemas.get(3).getName()); }
/** * Create a {@link HollowDataAccess} for a historical state after a double snapshot occurs, without a {@link HollowHistory}. * * @param version the version * @param previous the previous state * @param current the current state * @param ordinalRemapper the ordinal remapper * @return the data access for a history */ public HollowHistoricalStateDataAccess createHistoricalStateFromDoubleSnapshot(long version, HollowReadStateEngine previous, HollowReadStateEngine current, DiffEqualityMappingOrdinalRemapper ordinalRemapper) { HollowWriteStateEngine writeEngine = HollowWriteStateCreator.createWithSchemas(schemasWithoutKeys(previous.getSchemas())); IntMapOrdinalRemapper typeRemovedOrdinalLookupMaps = new IntMapOrdinalRemapper(); for(HollowSchema previousSchema : HollowSchemaSorter.dependencyOrderedSchemaList(previous)) { HollowTypeReadState previousTypeState = previous.getTypeState(previousSchema.getName()); String typeName = previousTypeState.getSchema().getName(); IntMap ordinalLookupMap; if(current.getTypeState(typeName) == null) { ordinalLookupMap = copyAllRecords(previousTypeState, ordinalRemapper, writeEngine); } else { HollowTypeReadState currentTypeState = current.getTypeState(typeName); BitSet currentlyPopulatedOrdinals = currentTypeState.getListener(PopulatedOrdinalListener.class).getPopulatedOrdinals(); ordinalLookupMap = copyUnmatchedRecords(previousTypeState, ordinalRemapper, currentlyPopulatedOrdinals, writeEngine); } typeRemovedOrdinalLookupMaps.addOrdinalRemapping(typeName, ordinalLookupMap); } Map<String, HollowHistoricalSchemaChange> schemaChanges = calculateSchemaChanges(previous, current, ordinalRemapper.getDiffEqualityMapping()); return new HollowHistoricalStateDataAccess(totalHistory, version, roundTripStateEngine(writeEngine), typeRemovedOrdinalLookupMaps, schemaChanges); }