private boolean isSearchable(HollowObjectSchema schema, int fieldNumber) { if(schema.getFieldType(fieldNumber) == FieldType.REFERENCE) { if(schema.getReferencedTypeState(fieldNumber).getSchema().getSchemaType() != SchemaType.OBJECT) return false; HollowObjectSchema refObjSchema = (HollowObjectSchema)schema.getReferencedTypeState(fieldNumber).getSchema(); if(refObjSchema.numFields() != 1) return false; return isSearchable(refObjSchema, 0); } return true; }
private TypeKey getKey(int recordIdx, HollowTypeReadState typeState, int ordinal, int[][] fieldPathIndexes) { if(fieldPathIndexes != null) { StringBuilder keyBuilder = new StringBuilder(); HollowObjectTypeReadState objState = (HollowObjectTypeReadState)typeState; for(int i=0;i<fieldPathIndexes.length;i++) { int curOrdinal = ordinal; HollowObjectTypeReadState curState = objState; for(int j=0;j<fieldPathIndexes[i].length - 1;j++) { curOrdinal = curState.readOrdinal(curOrdinal, fieldPathIndexes[i][j]); curState = (HollowObjectTypeReadState) curState.getSchema().getReferencedTypeState(fieldPathIndexes[i][j]); } if(i > 0) keyBuilder.append(":"); keyBuilder.append(HollowReadFieldUtils.fieldValueObject(curState, curOrdinal, fieldPathIndexes[i][fieldPathIndexes[i].length-1])); } return new TypeKey(recordIdx, ordinal, keyBuilder.toString()); } return new TypeKey(recordIdx, ordinal, "", "ORDINAL:"+ordinal); }
private boolean recordKeyEquals(HollowTypeReadState typeState, int ordinal, Object[] key, int[][] fieldPathIndexes) { HollowObjectTypeReadState objState = (HollowObjectTypeReadState)typeState; for(int i=0;i<fieldPathIndexes.length;i++) { int curOrdinal = ordinal; HollowObjectTypeReadState curState = objState; for(int j=0;j<fieldPathIndexes[i].length - 1;j++) { curOrdinal = curState.readOrdinal(curOrdinal, fieldPathIndexes[i][j]); curState = (HollowObjectTypeReadState) curState.getSchema().getReferencedTypeState(fieldPathIndexes[i][j]); } if(!HollowReadFieldUtils.fieldValueEquals(curState, curOrdinal, fieldPathIndexes[i][fieldPathIndexes[i].length-1], key[i])) return false; } return true; }
private Object readValue(int ordinal, int fieldIdx) { HollowObjectTypeReadState typeState = this.typeState; HollowObjectSchema schema = typeState.getSchema(); int lastFieldPath = fieldPathIndexes[fieldIdx].length - 1; for (int i = 0; i < lastFieldPath; i++) { int fieldPosition = fieldPathIndexes[fieldIdx][i]; ordinal = typeState.readOrdinal(ordinal, fieldPosition); typeState = (HollowObjectTypeReadState) schema.getReferencedTypeState(fieldPosition); schema = typeState.getSchema(); } return HollowReadFieldUtils.fieldValueObject(typeState, ordinal, fieldPathIndexes[fieldIdx][lastFieldPath]); }
int fieldPosition = fieldPathIndexes[fieldIdx][i]; ordinal = typeState.readOrdinal(ordinal, fieldPosition); typeState = (HollowObjectTypeReadState) schema.getReferencedTypeState(fieldPosition); schema = typeState.getSchema();
private void traverseObject(HollowObjectTypeReadState typeState, int ordinal) { HollowObjectSchema schema = typeState.getSchema(); for(int i=0;i<schema.numFields();i++) { if(schema.getFieldType(i) == FieldType.REFERENCE) { HollowTypeReadState refTypeState = schema.getReferencedTypeState(i); int refOrdinal = typeState.readOrdinal(ordinal, i); extractHollowRecord(refTypeState, refOrdinal); } } }
public SchemaDisplayField(String fieldPath, HollowObjectSchema parentSchema, int fieldNumber) { this.fieldPath = fieldPath; this.fieldName = parentSchema.getFieldName(fieldNumber); this.fieldType = parentSchema.getFieldType(fieldNumber); this.isSearchable = isSearchable(parentSchema, fieldNumber); this.referencedType = fieldType == FieldType.REFERENCE ? new SchemaDisplay(parentSchema.getReferencedTypeState(fieldNumber).getSchema(), fieldPath) : null; }
private int findKeyFieldHashCode(HollowObjectTypeReadState typeState, int ordinal, String[] keyFieldParts, int keyFieldPartPosition) { int schemaPosition = typeState.getSchema().getPosition(keyFieldParts[keyFieldPartPosition]); if(keyFieldPartPosition < keyFieldParts.length - 1) { HollowObjectTypeReadState nextPartTypeState = (HollowObjectTypeReadState) typeState.getSchema().getReferencedTypeState(schemaPosition); int nextOrdinal = typeState.readOrdinal(ordinal, schemaPosition); return findKeyFieldHashCode(nextPartTypeState, nextOrdinal, keyFieldParts, keyFieldPartPosition + 1); } else { return HollowReadFieldUtils.fieldHashCode(typeState, ordinal, schemaPosition); } }
private void addSchemaField(HollowObjectSchema schema, HollowObjectSchema keySchema, String keyField, String[] keyFieldParts, int keyFieldPartPosition) { int schemaPosition = schema.getPosition(keyFieldParts[keyFieldPartPosition]); if(keyFieldPartPosition < keyFieldParts.length - 1) { HollowObjectSchema nextPartSchema = (HollowObjectSchema) schema.getReferencedTypeState(schemaPosition).getSchema(); addSchemaField(nextPartSchema, keySchema, keyField, keyFieldParts, keyFieldPartPosition + 1); } else { keySchema.addField(keyField, schema.getFieldType(schemaPosition), schema.getReferencedType(schemaPosition)); } }
private boolean recordFieldMatchesKey(HollowObjectTypeReadState typeState, int ordinal, HollowObjectTypeReadState keyTypeState, int keyOrdinal, int keyFieldPosition, String[] keyFieldParts, int keyFieldPartPosition) { int schemaPosition = typeState.getSchema().getPosition(keyFieldParts[keyFieldPartPosition]); if(keyFieldPartPosition < keyFieldParts.length - 1) { HollowObjectTypeReadState nextPartTypeState = (HollowObjectTypeReadState) typeState.getSchema().getReferencedTypeState(schemaPosition); int nextOrdinal = typeState.readOrdinal(ordinal, schemaPosition); return recordFieldMatchesKey(nextPartTypeState, nextOrdinal, keyTypeState, keyOrdinal, keyFieldPosition, keyFieldParts, keyFieldPartPosition + 1); } else { return HollowReadFieldUtils.fieldsAreEqual(typeState, ordinal, schemaPosition, keyTypeState, keyOrdinal, keyFieldPosition); } }
private int fieldHash(int ordinal, int fieldIdx) { HollowObjectTypeReadState typeState = this.typeState; HollowObjectSchema schema = typeState.getSchema(); int lastFieldPath = fieldPathIndexes[fieldIdx].length - 1; for(int i=0;i<lastFieldPath;i++) { int fieldPosition = fieldPathIndexes[fieldIdx][i]; ordinal = typeState.readOrdinal(ordinal, fieldPosition); typeState = (HollowObjectTypeReadState) schema.getReferencedTypeState(fieldPosition); schema = typeState.getSchema(); } int hashCode = HollowReadFieldUtils.fieldHashCode(typeState, ordinal, fieldPathIndexes[fieldIdx][lastFieldPath]); switch(fieldTypes[fieldIdx]) { case STRING: case BYTES: return hashCode; default: return HashCodes.hashInt(hashCode); } }
private boolean fieldsAreEqual(int ordinal1, int ordinal2, int fieldIdx) { HollowObjectTypeReadState typeState = this.typeState; HollowObjectSchema schema = typeState.getSchema(); int lastFieldPath = fieldPathIndexes[fieldIdx].length - 1; for(int i=0;i<lastFieldPath;i++) { int fieldPosition = fieldPathIndexes[fieldIdx][i]; ordinal1 = typeState.readOrdinal(ordinal1, fieldPosition); ordinal2 = typeState.readOrdinal(ordinal2, fieldPosition); typeState = (HollowObjectTypeReadState) schema.getReferencedTypeState(fieldPosition); schema = typeState.getSchema(); } if(fieldTypes[fieldIdx] == FieldType.REFERENCE) return typeState.readOrdinal(ordinal1, fieldPathIndexes[fieldIdx][lastFieldPath]) == typeState.readOrdinal(ordinal2, fieldPathIndexes[fieldIdx][lastFieldPath]); return HollowReadFieldUtils.fieldsAreEqual(typeState, ordinal1, fieldPathIndexes[fieldIdx][lastFieldPath], typeState, ordinal2, fieldPathIndexes[fieldIdx][lastFieldPath]); }
private BitSet attemptReferenceTraversalQuery(HollowObjectTypeReadState typeState, int fieldIdx, String fieldValue) { HollowTypeReadState referencedTypeState = typeState.getSchema().getReferencedTypeState(fieldIdx); if(referencedTypeState.getSchema().getSchemaType() == SchemaType.OBJECT) { HollowObjectTypeReadState refObjTypeState = (HollowObjectTypeReadState)referencedTypeState; HollowObjectSchema refSchema = refObjTypeState.getSchema(); if(refSchema.numFields() == 1) { if(refSchema.getFieldType(0) == FieldType.REFERENCE) { BitSet refQueryMatches = attemptReferenceTraversalQuery(refObjTypeState, 0, fieldValue); if(refQueryMatches != null) return queryBasedOnMatchedReferences(typeState, fieldIdx, refQueryMatches); } else { Object queryValue = castQueryValue(fieldValue, refSchema.getFieldType(0)); if(queryValue != null) { BitSet refQueryMatches = queryBasedOnValueMatches(refObjTypeState, 0, queryValue); if(refQueryMatches.cardinality() > 0) return queryBasedOnMatchedReferences(typeState, fieldIdx, refQueryMatches); } } } } return null; }
private boolean matchIsEqual(FixedLengthElementArray matchHashTable, long hashBucketBit, Object[] query) { HollowHashIndexState hashState = hashStateVolatile; for(int i = 0; i< hashState.getMatchFields().length; i++) { HollowHashIndexField field = hashState.getMatchFields()[i]; int hashOrdinal = (int)matchHashTable.getElementValue(hashBucketBit + hashState.getOffsetPerTraverserField()[field.getBaseIteratorFieldIdx()], hashState.getBitsPerTraverserField()[field.getBaseIteratorFieldIdx()]) - 1; HollowTypeReadState readState = field.getBaseDataAccess(); int[] fieldPath = field.getSchemaFieldPositionPath(); if(fieldPath.length == 0) { if (!query[i].equals(hashOrdinal)) return false; } else { for(int j=0;j<fieldPath.length - 1;j++) { HollowObjectTypeReadState objectAccess = (HollowObjectTypeReadState)readState; readState = objectAccess.getSchema().getReferencedTypeState(fieldPath[j]); hashOrdinal = objectAccess.readOrdinal(hashOrdinal, fieldPath[j]); } HollowObjectTypeReadState objectAccess = (HollowObjectTypeReadState)readState; int fieldIdx = fieldPath[fieldPath.length-1]; if(hashOrdinal == -1 || !HollowReadFieldUtils.fieldValueEquals(objectAccess, hashOrdinal, fieldIdx, query[i])) { return false; } } } return true; }
private void writeKeyField(HollowObjectTypeReadState typeState, int ordinal, HollowObjectWriteRecord rec, String keyField, String[] keyFieldParts, int keyFieldPartPosition) { int schemaPosition = typeState.getSchema().getPosition(keyFieldParts[keyFieldPartPosition]); if(keyFieldPartPosition < keyFieldParts.length - 1) { HollowObjectTypeReadState nextPartTypeState = (HollowObjectTypeReadState) typeState.getSchema().getReferencedTypeState(schemaPosition); int nextOrdinal = typeState.readOrdinal(ordinal, schemaPosition); writeKeyField(nextPartTypeState, nextOrdinal, rec, keyField, keyFieldParts, keyFieldPartPosition + 1);
private int getMatchHash(int matchIdx) { int matchHash = 0; for(int i=0;i<preindexer.getMatchFieldSpecs().length;i++) { HollowHashIndexField field = preindexer.getMatchFieldSpecs()[i]; int ordinal = preindexer.getTraverser().getMatchOrdinal(matchIdx, field.getBaseIteratorFieldIdx()); HollowTypeReadState readState = field.getBaseDataAccess(); int[] fieldPath = field.getSchemaFieldPositionPath(); if(fieldPath.length == 0) { matchHash ^= HashCodes.hashInt(ordinal); } else { for(int j=0;j<fieldPath.length-1;j++) { HollowObjectTypeReadState objectAccess = (HollowObjectTypeReadState)readState; readState = objectAccess.getSchema().getReferencedTypeState(fieldPath[j]); ordinal = objectAccess.readOrdinal(ordinal, fieldPath[j]); } int fieldHashCode = ordinal == -1 ? -1 : HollowReadFieldUtils.fieldHashCode((HollowObjectTypeDataAccess) readState, ordinal, fieldPath[fieldPath.length-1]); matchHash ^= HashCodes.hashInt(fieldHashCode); } } return matchHash; }
public HollowDiffObjectCountingNode(HollowDiff diff, HollowTypeDiff topLevelTypeDiff, HollowDiffNodeIdentifier nodeId, HollowObjectTypeReadState fromState, HollowObjectTypeReadState toState) { super(diff, topLevelTypeDiff, nodeId); this.fromState = fromState; this.toState = toState; this.fromSchema = fromState == null ? emptySchema(toState.getSchema()) : fromState.getSchema(); this.toSchema = toState == null ? emptySchema(fromState.getSchema()) : toState.getSchema(); if(!fromSchema.getName().equals(toSchema.getName())) throw new IllegalArgumentException("Cannot diff between two schemas with different names: from '" + fromSchema.getName() + "' to '" + toSchema.getName() + "'"); this.unionSchema = fromSchema.findUnionSchema(toSchema); this.fieldNodes = new HollowDiffCountingNode[unionSchema.numFields()]; this.fromFieldMapping = createFieldMapping(unionSchema, fromSchema); this.toFieldMapping = createFieldMapping(unionSchema, toSchema); this.fieldRequiresMissingFieldTraversal = new boolean[unionSchema.numFields()]; this.fieldEqualOrdinalFilters = new DiffEqualOrdinalFilter[unionSchema.numFields()]; for(int i=0;i<unionSchema.numFields();i++) { int fromFieldIndex = fromSchema.getPosition(unionSchema.getFieldName(i)); int toFieldIndex = toSchema.getPosition(unionSchema.getFieldName(i)); if(unionSchema.getFieldType(i) == FieldType.REFERENCE) { HollowTypeReadState refFromState = fromFieldIndex == -1 ? null : fromSchema.getReferencedTypeState(fromFieldIndex); HollowTypeReadState refToState = toFieldIndex == -1 ? null : toSchema.getReferencedTypeState(toFieldIndex); fieldNodes[i] = getHollowDiffCountingNode(refFromState, refToState, unionSchema.getFieldName(i)); fieldEqualOrdinalFilters[i] = new DiffEqualOrdinalFilter(equalityMapping.getEqualOrdinalMap(unionSchema.getReferencedType(i))); if(refFromState == null || refToState == null || equalityMapping.requiresMissingFieldTraversal(unionSchema.getReferencedType(i))) fieldRequiresMissingFieldTraversal[i] = true; } else { HollowDiffNodeIdentifier childNodeId = new HollowDiffNodeIdentifier(nodeId, unionSchema.getFieldName(i), unionSchema.getFieldType(i).toString()); fieldNodes[i] = new HollowDiffFieldCountingNode(diff, topLevelTypeDiff, childNodeId, fromState, toState, unionSchema, i); } } }
private boolean intermediateMatchIsEqual(int matchIdx, long hashBucketBit) { for(int i=0;i<preindexer.getMatchFieldSpecs().length;i++) { HollowHashIndexField field = preindexer.getMatchFieldSpecs()[i]; int matchOrdinal = preindexer.getTraverser().getMatchOrdinal(matchIdx, field.getBaseIteratorFieldIdx()); int hashOrdinal = (int)intermediateMatchHashTable.getElementValue(hashBucketBit + offsetPerTraverserField[field.getBaseIteratorFieldIdx()], bitsPerTraverserField[field.getBaseIteratorFieldIdx()]) - 1; HollowTypeReadState readState = field.getBaseDataAccess(); int[] fieldPath = field.getSchemaFieldPositionPath(); if(fieldPath.length == 0) { if(matchOrdinal != hashOrdinal) return false; } else { for(int j=0;j<fieldPath.length - 1;j++) { HollowObjectTypeReadState objectAccess = (HollowObjectTypeReadState)readState; readState = objectAccess.getSchema().getReferencedTypeState(fieldPath[j]); matchOrdinal = objectAccess.readOrdinal(matchOrdinal, fieldPath[j]); hashOrdinal = objectAccess.readOrdinal(hashOrdinal, fieldPath[j]); } if(matchOrdinal != hashOrdinal) { HollowObjectTypeReadState objectAccess = (HollowObjectTypeReadState)readState; int fieldIdx = fieldPath[fieldPath.length-1]; if(isAnyFieldNull(matchOrdinal, hashOrdinal) || !HollowReadFieldUtils.fieldsAreEqual(objectAccess, matchOrdinal, fieldIdx, objectAccess, hashOrdinal, fieldIdx)) return false; } } } return true; }