| | |
| | | */ |
| | | package org.opends.server.backends.jeb; |
| | | |
| | | import java.util.Comparator; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | |
| | | import org.forgerock.opendj.ldap.spi.IndexingOptions; |
| | | import org.opends.server.api.ExtensibleIndexer; |
| | | import org.opends.server.api.SubstringMatchingRule; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | |
| | | /** |
| | | * An implementation of an Indexer for attribute substrings. |
| | | */ |
| | | public class SubstringIndexer extends Indexer |
| | | public class SubstringIndexer extends ExtensibleIndexer |
| | | { |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * The comparator for index keys generated by this class. |
| | | */ |
| | | private static final Comparator<byte[]> comparator = |
| | | new AttributeIndex.KeyComparator(); |
| | | |
| | | /** |
| | | * The attribute type for which this instance will |
| | | * generate index keys. |
| | | */ |
| | | private AttributeType attributeType; |
| | | private SubstringMatchingRule substringRule; |
| | | private IndexingOptions indexingOptions; |
| | | |
| | | /** |
| | |
| | | public SubstringIndexer(AttributeType attributeType, |
| | | IndexingOptions indexingOptions) |
| | | { |
| | | this.attributeType = attributeType; |
| | | this.substringRule = attributeType.getSubstringMatchingRule(); |
| | | this.indexingOptions = indexingOptions; |
| | | } |
| | | |
| | | /** |
| | | * Get a string representation of this object. The returned value is |
| | | * used to name an index created using this object. |
| | | * @return A string representation of this object. |
| | | */ |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public String toString() |
| | | public String getIndexID() |
| | | { |
| | | return attributeType.getNameOrOID() + ".substring"; |
| | | // TODO Auto-generated method stub |
| | | throw new RuntimeException(); |
| | | } |
| | | |
| | | /** |
| | | * Get the comparator that must be used to compare index keys |
| | | * generated by this class. |
| | | * |
| | | * @return A byte array comparator. |
| | | */ |
| | | /** {@inheritDoc} */ |
| | | @Override |
| | | public Comparator<byte[]> getComparator() |
| | | public String getExtensibleIndexID() |
| | | { |
| | | return comparator; |
| | | } |
| | | |
| | | /** |
| | | * Generate the set of index keys for an entry. |
| | | * |
| | | * @param entry The entry. |
| | | * @param keys The set into which the generated keys will be inserted. |
| | | */ |
| | | @Override |
| | | public void indexEntry(Entry entry, Set<byte[]> keys) |
| | | { |
| | | List<Attribute> attrList = |
| | | entry.getAttribute(attributeType); |
| | | if (attrList != null) |
| | | { |
| | | indexAttribute(attrList, keys); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Generate the set of index keys to be added and the set of index keys |
| | | * to be deleted for an entry that has been replaced. |
| | | * |
| | | * @param oldEntry The original entry contents. |
| | | * @param newEntry The new entry contents. |
| | | * @param modifiedKeys The map into which the modified keys will be inserted. |
| | | */ |
| | | @Override |
| | | public void replaceEntry(Entry oldEntry, Entry newEntry, |
| | | Map<byte[], Boolean> modifiedKeys) |
| | | { |
| | | List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true); |
| | | List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true); |
| | | |
| | | indexAttribute(oldAttributes, modifiedKeys, false); |
| | | indexAttribute(newAttributes, modifiedKeys, true); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Generate the set of index keys to be added and the set of index keys |
| | | * to be deleted for an entry that was modified. |
| | | * |
| | | * @param oldEntry The original entry contents. |
| | | * @param newEntry The new entry contents. |
| | | * @param mods The set of modifications that were applied to the entry. |
| | | * @param modifiedKeys The map into which the modified keys will be inserted. |
| | | */ |
| | | @Override |
| | | public void modifyEntry(Entry oldEntry, Entry newEntry, |
| | | List<Modification> mods, |
| | | Map<byte[], Boolean> modifiedKeys) |
| | | { |
| | | List<Attribute> newAttributes = newEntry.getAttribute(attributeType, true); |
| | | List<Attribute> oldAttributes = oldEntry.getAttribute(attributeType, true); |
| | | |
| | | indexAttribute(oldAttributes, modifiedKeys, false); |
| | | indexAttribute(newAttributes, modifiedKeys, true); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Generate the set of substring index keys for an attribute. |
| | | * @param attrList The attribute for which substring keys are required. |
| | | * @param keys The set into which the generated keys will be inserted. |
| | | */ |
| | | private void indexAttribute(List<Attribute> attrList, |
| | | Set<byte[]> keys) |
| | | { |
| | | if (attrList == null) return; |
| | | for (Attribute attr : attrList) |
| | | { |
| | | if (!attr.isVirtual()) |
| | | { |
| | | SubstringMatchingRule rule = |
| | | attr.getAttributeType().getSubstringMatchingRule(); |
| | | for (AttributeValue value : attr) |
| | | { |
| | | getKeys(rule, value, keys); |
| | | } |
| | | } |
| | | } |
| | | return "substring"; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @param attrValue A byte array containing the normalized attribute value |
| | | * @param keys A set into which the keys will be inserted. |
| | | */ |
| | | private void getKeys(SubstringMatchingRule rule, AttributeValue attrValue, |
| | | Set<byte[]> keys) |
| | | @Override |
| | | public void getKeys(AttributeValue attrValue, Set<byte[]> keys) |
| | | { // TODO merge with ExtensibleIndexer.getKeys(attrValue, keys); |
| | | try |
| | | { |
| | | byte[] value = rule.normalizeAttributeValue(attrValue.getValue()).toByteArray(); |
| | | byte[] value = substringRule.normalizeAttributeValue(attrValue.getValue()).toByteArray(); |
| | | |
| | | // Example: The value is ABCDE and the substring length is 3. |
| | | // We produce the keys ABC BCD CDE DE E |
| | |
| | | return keyBytes; |
| | | } |
| | | |
| | | /** |
| | | * Generate the set of index keys for an attribute. |
| | | * @param attrList The attribute to be indexed. |
| | | * @param modifiedKeys The map into which the modified |
| | | * keys will be inserted. |
| | | * @param insert <code>true</code> if generated keys should |
| | | * be inserted or <code>false</code> otherwise. |
| | | */ |
| | | private void indexAttribute(List<Attribute> attrList, |
| | | Map<byte[], Boolean> modifiedKeys, |
| | | Boolean insert) |
| | | { |
| | | if (attrList == null) return; |
| | | |
| | | for (Attribute attr : attrList) |
| | | { |
| | | if (!attr.isVirtual()) |
| | | { |
| | | SubstringMatchingRule rule = |
| | | attr.getAttributeType().getSubstringMatchingRule(); |
| | | for (AttributeValue value : attr) |
| | | { |
| | | getKeys(rule, value, modifiedKeys, insert); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decompose an attribute value into a set of substring index keys. |
| | | * The ID of the entry containing this value should be inserted |
| | | * into the list of each of these keys. |
| | | * |
| | | * @param value A byte array containing the normalized attribute value |
| | | * @param modifiedKeys The map into which the modified |
| | | * keys will be inserted. |
| | | * @param insert <code>true</code> if generated keys should |
| | | * be inserted or <code>false</code> otherwise. |
| | | */ |
| | | private void getKeys(SubstringMatchingRule rule, AttributeValue value, |
| | | Map<byte[], Boolean> modifiedKeys, Boolean insert) |
| | | { // TODO merge with ExtensibleIndexer.getKeys(attrValue, modifiedKeys, insert); |
| | | Set<byte[]> keys = new HashSet<byte[]>(); |
| | | getKeys(rule, value, keys); |
| | | ExtensibleIndexer.computeModifiedKeys(modifiedKeys, insert, keys); |
| | | } |
| | | |
| | | } |