private CompositeIndex addCompositeIndex(Schema schema, SchemaCompositeIndex schemaIndex) { // Get fields corresponding to specified storage IDs final int[] storageIds = Ints.toArray(schemaIndex.getIndexedFields()); if (storageIds.length < 2 || storageIds.length > Database.MAX_INDEXED_FIELDS) throw new IllegalArgumentException("invalid " + schemaIndex + ": can't index " + storageIds.length + " fields"); final ArrayList<SimpleField<?>> list = new ArrayList<>(storageIds.length); int count = 0; for (int storageId : storageIds) { final Field<?> field = this.fields.get(storageId); if (!(field instanceof SimpleField)) { throw new IllegalArgumentException("invalid " + schemaIndex + ": no simple field with storage ID " + storageId + " found"); } final SimpleField<?> simpleField = (SimpleField<?>)field; if (simpleField.parent != null) { throw new IllegalArgumentException("invalid " + schemaIndex + ": simple field with storage ID " + storageId + " is a sub-field of a complex field"); } list.add(simpleField); } // Create and add index final CompositeIndex index = new CompositeIndex(schemaIndex.getName(), schemaIndex.getStorageId(), schema, this, list); this.addSchemaItem(this.compositeIndexes, this.compositeIndexesByName, index); return index; } }
@Override SchemaCompositeIndex toSchemaItem(JSimpleDB jdb) { final SchemaCompositeIndex schemaIndex = new SchemaCompositeIndex(); this.initialize(jdb, schemaIndex); return schemaIndex; }
@Override @SuppressWarnings("unchecked") public SchemaObjectType clone() { final SchemaObjectType clone = (SchemaObjectType)super.clone(); clone.schemaFields = new TreeMap<>(clone.schemaFields); for (Map.Entry<Integer, SchemaField> entry : clone.schemaFields.entrySet()) entry.setValue(entry.getValue().clone()); clone.schemaCompositeIndexes = new TreeMap<>(clone.schemaCompositeIndexes); for (Map.Entry<Integer, SchemaCompositeIndex> entry : clone.schemaCompositeIndexes.entrySet()) entry.setValue(entry.getValue().clone()); return clone; } }
@Override void readSubElements(XMLStreamReader reader, int formatVersion) throws XMLStreamException { this.indexedFields.clear(); while (this.expect(reader, true, XMLConstants.INDEXED_FIELD_TAG)) { this.indexedFields.add(this.getIntAttr(reader, XMLConstants.STORAGE_ID_ATTRIBUTE)); this.expectClose(reader); // </IndexedField> } if (this.indexedFields instanceof ArrayList) ((ArrayList<?>)this.indexedFields).trimToSize(); }
CompositeIndex(JsckInfo info, int schemaVersion, SchemaObjectType objectType, SchemaCompositeIndex index) { super(info, index.getStorageId()); this.fieldStorageIds = index.getIndexedFields().stream().mapToInt(Integer::intValue).toArray(); this.fieldTypes = new FieldType<?>[this.fieldStorageIds.length]; for (int i = 0; i < this.fieldTypes.length; i++) { final SimpleSchemaField field = (SimpleSchemaField)objectType.getSchemaFields().get(fieldStorageIds[i]); this.fieldTypes[i] = this.info.findFieldType(schemaVersion, field).genericizeForIndex(); } }
index.validate(); final String indexName = index.getName(); if (compositeIndexesByName.put(indexName, index) != null) throw new InvalidSchemaException("duplicate composite index name `" + indexName + "'"); for (int storageId : index.getIndexedFields()) { final SchemaField field = this.schemaFields.get(storageId); if (!(field instanceof SimpleSchemaField)) final SchemaCompositeIndex previous = compositeIndexFields.put(index.getIndexedFields(), index); if (previous != null) throw new InvalidSchemaException("duplicate " + index + " (duplicates " + previous + ")");
void initialize(JSimpleDB jdb, SchemaCompositeIndex schemaIndex) { super.initialize(jdb, schemaIndex); for (JSimpleField jfield : this.jfields) schemaIndex.getIndexedFields().add(jfield.getStorageId()); }
index.readXML(reader, formatVersion); final int storageId = index.getStorageId(); final SchemaCompositeIndex previous = this.schemaCompositeIndexes.put(storageId, index); if (previous != null) {
this.typeCompositeIndexMap.put(type.getStorageId(), compositeIndexMap); for (SchemaCompositeIndex compositeIndex : type.getSchemaCompositeIndexes().values()) { if (compositeIndexMap.put(compositeIndex.getName(), compositeIndex) != null) throw new IllegalArgumentException("schema model is invalid");
diffs.add("added " + thisIndex); else { final Diffs indexDiffs = thisIndex.differencesFrom(thatIndex); if (!indexDiffs.isEmpty()) diffs.add("changed " + thatIndex, indexDiffs);
/** * Verify a composite index entry. */ private void verifyCompositeIndexEntry(JsckInfo info, ObjId id, SchemaCompositeIndex index, HashMap<Integer, byte[]> simpleFieldValues) { // Build index entry final ByteWriter writer = new ByteWriter(); UnsignedIntEncoder.write(writer, index.getStorageId()); for (int storageId : index.getIndexedFields()) { // Get the field's value byte[] value = simpleFieldValues.get(storageId); if (value == null) value = this.simpleFieldTypes.get(storageId).getDefaultValue(); // Append to index entry writer.write(value); } id.writeTo(writer); // Verify index entry this.verifyIndexEntry(info, id, writer.getBytes(), "" + index); }