@Override public boolean matches(JsonValue value) throws Exception { if (!(value instanceof JsonRecord)) { return false; } JsonRecord rec = (JsonRecord) value; // assumption: field names are sorted int nr = rec.size(); // number of fields in record int ns = fieldsByName.length; // number of fields in schema int pr = 0; // current field in record int ps = 0; // current field in schema // zip join Iterator<Entry<JsonString, JsonValue>> recIt = rec.iteratorSorted(); Entry<JsonString, JsonValue> recEntry = null; if (nr > 0) recEntry = recIt.next(); while (pr < nr && ps < ns) { Field schemaField = fieldsByName[ps]; JsonString recordFieldName = recEntry.getKey(); // compare int cmp = schemaField.getName().compareTo(recordFieldName); if (cmp < 0) { // field is in schema but not in record if (!schemaField.isOptional) { return false; } ps++; } else if (cmp == 0) { // field is schema and in record if (!schemaField.getSchema().matches(recEntry.getValue())) { return false; } ps++; pr++; if (pr < nr) { assert recIt.hasNext(); recEntry = recIt.next(); } } else { // field is not in schema but in record if (additional == null || !additional.matches(recEntry.getValue())) { return false; } pr++; if (pr < nr) { assert recIt.hasNext(); recEntry = recIt.next(); } } } // only one of them still has fields, i.e., the while loops are exclusive while (pr < nr) { // there are fields left in the record if (additional == null || !additional.matches(recEntry.getValue())) { return false; } pr++; if (pr < nr) { assert recIt.hasNext(); recEntry = recIt.next(); } } assert !recIt.hasNext(); while (ps < ns) { // therea are fields left in the schema if (!fieldsByName[ps].isOptional) { return false; } ps++; } // everything ok return true; }