Changeset 05b3ea1


Ignore:
Timestamp:
Jul 15, 2010, 1:46:22 PM (8 years ago)
Author:
Michael Seifert <mseifert@…>
Branches:
master
Children:
f6a2d3c
Parents:
39730c4
Message:

Reimplemented IndexHierarchy?. It now represents a tree with one node for each indexed object

Location:
src/main/java/de/erichseifert/warp/io/search
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/main/java/de/erichseifert/warp/io/search/DefaultReplayIndexer.java

    r39730c4 r05b3ea1  
    3636import de.erichseifert.warp.ReplayChangeEvent.EventType;
    3737import de.erichseifert.warp.io.ReplayStorage;
     38import de.erichseifert.warp.io.search.IndexHierarchy.Node;
    3839import de.erichseifert.warp.io.search.indices.Index;
    3940import de.erichseifert.warp.io.search.indices.Index.Range;
     
    5253 */
    5354public class DefaultReplayIndexer extends AbstractReplayIndexer {
     55        private final IndexHierarchy hierarchy;
    5456        private final Map<String, Index> indices;
    5557        private transient ReplayStorage storage;
     
    5961         */
    6062        public DefaultReplayIndexer(ReplayStorage storage) {
     63                hierarchy = new IndexHierarchy();
    6164                indices = new HashMap<String, Index>();
    6265        }
     
    6871                        ReplayDescriptor descriptor = evt.getDescriptorOld();
    6972                        Replay replay = storage.getReplay(descriptor);
    70                         //TODO removeIndex(replay);
     73                        removeIndex(replay);
    7174                }
    7275                if (evt.getType() == EventType.ADD || evt.getType() == EventType.CHANGE) {
     
    120123         * @throws IntrospectionException
    121124         */
    122         private void createIndices(Object obj, IndexHierarchy hierarchy, long listIndex) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException, IntrospectionException {
     125        private void createIndices(Object obj, IndexHierarchy.Node parentNode, long listIndex) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException, IntrospectionException {
    123126                Map<IndexedProperty, Set<Indexable>> indexables = getIndexables(obj);
    124127
    125                 // Initialize hierarchy
    126                 if (hierarchy == null) {
    127                         hierarchy = new IndexHierarchy();
    128                         if (obj instanceof Replay) {
    129                                 hierarchy.put("#replay", ((Replay) obj).getDescriptor().getId());
    130                         }
    131                         // TODO: else throw exception
     128                if (parentNode == null && obj instanceof Replay) {
     129                        parentNode = hierarchy.createNode("#replay", ((Replay) obj).getDescriptor().getId());
    132130                }
    133131
     
    136134                        int position = 0;
    137135                        for (Object iterableChild : (Iterable<?>) obj) {
    138                                 IndexHierarchy iterableHierarchy = new IndexHierarchy(hierarchy);
    139                                 iterableHierarchy.put("iterator", position);
    140                                 createIndices(iterableChild, new IndexHierarchy(iterableHierarchy), 0);
     136                                Node node = parentNode.createNode("iterator", position);
     137                                createIndices(iterableChild, node, 0);
    141138                                position++;
    142139                        }
     
    145142                        // Iterate over all indexed properties
    146143                        for (Map.Entry<IndexedProperty, Set<Indexable>> entry : indexables.entrySet()) {
    147                                 IndexHierarchy propertyBranch = new IndexHierarchy(hierarchy);
    148144                                IndexedProperty property = entry.getKey();
    149145                                Set<Indexable> indexableAnnotations = entry.getValue();
    150146
    151147                                // Add the currently indexed object to the parent hierarchy
    152                                 propertyBranch.put(property.getPropertyGetterName(), listIndex);
     148                                Node node = parentNode.createNode(property.getPropertyGetterName(), listIndex);
    153149
    154150                                // Step into indexed children
     
    157153                                        Method getter = clazz.getMethod(property.getPropertyGetterName());
    158154                                        Object indexedChild = getter.invoke(obj);
    159                                         createIndices(indexedChild, new IndexHierarchy(propertyBranch), 0);
     155                                        createIndices(indexedChild, node, 0);
    160156                                }
    161157
     
    168164                                                indices.put(indexable.indexName(), index);
    169165                                        }
    170                                         index.index(propertyBranch);
    171                                 }
    172                         }
     166                                        index.index(node);
     167                                }
     168                        }
     169                }
     170        }
     171
     172        private void removeIndex(Replay replay) {
     173                for (Index index : indices.values()) {
     174                        Node node = hierarchy.remove("#replay", replay.getDescriptor().getId());
     175                        index.unindex(node);
    173176                }
    174177        }
     
    184187                        if (index != null) {
    185188                                Range range = ranges.get(indexName);
    186                                 Set<IndexHierarchy> queryResults = index.search(queryValue, range);
    187                                 for (IndexHierarchy resultHierarchy : queryResults) {
     189                                Set<Node> queryResults = index.search(queryValue, range);
     190                                for (Node resultNode : queryResults) {
    188191                                        // The parent element of an index hierarchy must be a replay
    189                                         long replayID = resultHierarchy.getFirstElement().getId();
     192                                        long replayID = resultNode.getRootNode().getId();
    190193                                        ReplayDescriptor descriptor = storage.load(replayID).get(0);
    191194                                        results.add(descriptor);
     
    202205
    203206        @Override
    204         public Object getChildObject(IndexHierarchy hierarchy) {
     207        public Object getChildObject(Node node) {
    205208                Object parentObj = null;
    206209                Object childObject = null;
    207                 for (IndexHierarchy.Entry entry : hierarchy) {
    208                         if ("#replay".equals(entry.getPropertyGetterName())) {
    209                                 ReplayDescriptor descriptor = storage.load(entry.getId()).get(0);
     210                for (Node pathNode : node.getPath()) {
     211                        if ("#replay".equals(pathNode.getPropertyGetterName())) {
     212                                ReplayDescriptor descriptor = storage.load(pathNode.getId()).get(0);
    210213                                parentObj = storage.getReplay(descriptor);
    211214                                continue;
    212215                        }
    213216                        childObject = null;
    214                         String getterName = entry.getPropertyGetterName();
    215                         long id = entry.getId();
     217                        String getterName = pathNode.getPropertyGetterName();
     218                        long id = pathNode.getId();
    216219                        Method getter = null;
    217220                        try {
  • src/main/java/de/erichseifert/warp/io/search/IndexHierarchy.java

    r39730c4 r05b3ea1  
    2525import java.util.Iterator;
    2626import java.util.LinkedList;
     27import java.util.List;
    2728
    28 public class IndexHierarchy implements Iterable<IndexHierarchy.Entry>, Serializable  {
    29         private final LinkedList<Entry> hierarchy;
     29public class IndexHierarchy implements Iterable<IndexHierarchy.Node>, Serializable  {
     30        private final List<Node> rootNodes;
    3031
    31         public static class Entry implements Serializable {
     32        public static class Node implements Iterable<Node>, Serializable {
     33                private final List<Node> childNodes;
    3234                private final String propertyGetterName;
    3335                private final long id;
    3436
    35                 public Entry(String propertyGetterName, long id) {
     37                private Node parent;
     38
     39                private Node(Node parent, String propertyGetterName, long id) {
     40                        this.parent = parent;
    3641                        this.propertyGetterName = propertyGetterName;
    3742                        this.id = id;
     43                        childNodes = new LinkedList<Node>();
     44                }
     45
     46                public List<Node> getChildNodes() {
     47                        return childNodes;
     48                }
     49
     50                public boolean isRootNode() {
     51                        if (parent == null) {
     52                                return true;
     53                        }
     54                        return false;
     55                }
     56
     57                public boolean isLeafNode() {
     58                        if (childNodes.isEmpty()) {
     59                                return true;
     60                        }
     61                        return false;
     62                }
     63
     64                @Override
     65                public Iterator<Node> iterator() {
     66                        return childNodes.iterator();
    3867                }
    3968
     
    4675                }
    4776
     77                public int size() {
     78                        int size = 0;
     79                        for (Node node : childNodes) {
     80                                size += 1 + node.size();
     81                        }
     82                        return size;
     83                }
     84
     85                public Node remove(String propertyGetterName, long id) {
     86                        Node nodeRemoved = null;
     87                        for (Node node : childNodes) {
     88                                if (node.getId() == id && node.getPropertyGetterName().equals(propertyGetterName)) {
     89                                        childNodes.remove(node);
     90                                        nodeRemoved = node;
     91                                }
     92                                else {
     93                                        nodeRemoved = node.remove(propertyGetterName, id);
     94                                }
     95                        }
     96                        return nodeRemoved;
     97                }
     98
     99                public Node createNode(String propertyGetterName, long id) {
     100                        Node node = new Node(this, propertyGetterName, id);
     101                        childNodes.add(node);
     102                        return node;
     103                }
     104
     105                public Node getRootNode() {
     106                        if  (isRootNode()) {
     107                                return this;
     108                        }
     109                        return parent.getRootNode();
     110                }
     111
     112                public List<Node> getPath() {
     113                        List<Node> path = new LinkedList<Node>();
     114                        if  (!isRootNode()) {
     115                                path.addAll(getParent().getPath());
     116                        }
     117                        path.add(this);
     118                        return path;
     119                }
     120
    48121                @Override
    49122                public String toString() {
    50123                        return propertyGetterName+"="+id;
    51124                }
     125
     126                public Node getParent() {
     127                        return parent;
     128                }
    52129        }
    53130
    54131        public IndexHierarchy() {
    55                 hierarchy = new LinkedList<Entry>();
     132                rootNodes = new LinkedList<Node>();
    56133        }
    57134
    58         public IndexHierarchy(IndexHierarchy hierarchy) {
    59                 this.hierarchy = hierarchy.getHierarchy();
     135        public Node createNode(String propertyGetterName, long id) {
     136                Node node = new Node(null, propertyGetterName, id);
     137                rootNodes.add(node);
     138                return node;
    60139        }
    61140
    62         public void put(String propertyGetterName, long id) {
    63                 hierarchy.add(new Entry(propertyGetterName, id));
    64         }
    65 
    66         public Entry getFirstElement() {
    67                 return hierarchy.getFirst();
    68         }
    69 
    70         public Entry getLastElement() {
    71                 return hierarchy.getLast();
    72         }
    73 
    74         private LinkedList<Entry> getHierarchy() {
    75                 return new LinkedList<Entry>(hierarchy);
     141        public Node remove(String propertyGetterName, long id) {
     142                Node nodeRemoved = null;
     143                for (Node node : rootNodes) {
     144                        if (node.getId() == id && node.getPropertyGetterName().equals(propertyGetterName)) {
     145                                rootNodes.remove(node);
     146                                nodeRemoved = node;
     147                        }
     148                        else {
     149                                nodeRemoved = node.remove(propertyGetterName, id);
     150                        }
     151                }
     152                return nodeRemoved;
    76153        }
    77154
    78155        @Override
    79         public Iterator<Entry> iterator() {
    80                 return hierarchy.iterator();
     156        public Iterator<Node> iterator() {
     157                return rootNodes.iterator();
     158        }
     159
     160        public int size() {
     161                int size = 0;
     162                for (Node node : rootNodes) {
     163                        size += 1 + node.size();
     164                }
     165                return size;
    81166        }
    82167}
  • src/main/java/de/erichseifert/warp/io/search/ReplayIndexer.java

    r39730c4 r05b3ea1  
    2929import de.erichseifert.warp.ReplayDescriptor;
    3030import de.erichseifert.warp.io.ReplayStorage;
     31import de.erichseifert.warp.io.search.IndexHierarchy.Node;
    3132import de.erichseifert.warp.io.search.indices.Index.Range;
    3233
     
    7576        Set<String> getIndexNames();
    7677
    77         Object getChildObject(IndexHierarchy hierarchy);
     78        Object getChildObject(Node node);
    7879
    7980        void setStorage(ReplayStorage storage);
  • src/main/java/de/erichseifert/warp/io/search/indices/AbstractIndex.java

    r39730c4 r05b3ea1  
    2727import java.util.Set;
    2828
    29 import de.erichseifert.warp.io.search.IndexHierarchy;
    3029import de.erichseifert.warp.io.search.IndexedProperty;
    3130import de.erichseifert.warp.io.search.ReplayIndexer;
     31import de.erichseifert.warp.io.search.IndexHierarchy.Node;
    3232
    3333/**
     
    3939        private final ReplayIndexer indexer;
    4040        private final IndexedProperty property;
    41         private final Map<Object, Set<IndexHierarchy>> indexedValues;
     41        private final Map<Object, Set<Node>> indexedValues;
    4242
    4343        /**
     
    5050                this.indexer = indexer;
    5151                this.property= property;
    52                 indexedValues = new HashMap<Object, Set<IndexHierarchy>>();
     52                indexedValues = new HashMap<Object, Set<Node>>();
    5353        }
    5454
     
    5858         * @return Value of the property.
    5959         */
    60         protected Object getValue(IndexHierarchy hierarchy) {
    61                 Object indexedObject = indexer.getChildObject(hierarchy);
     60        protected Object getValue(Node node) {
     61                Object indexedObject = indexer.getChildObject(node);
    6262                return indexedObject;
    6363        }
     
    6868         * @return Results.
    6969         */
    70         protected Set<IndexHierarchy> get(Object value) {
     70        protected Set<Node> get(Object value) {
    7171                return indexedValues.get(value);
    7272        }
     
    7777         * @param hierarchy Indexing hierarchy.
    7878         */
    79         protected void put(Object value, IndexHierarchy hierarchy) {
    80                 Set<IndexHierarchy> hierarchies = indexedValues.get(value);
    81                 if (hierarchies == null) {
    82                         hierarchies = new HashSet<IndexHierarchy>();
    83                         indexedValues.put(value, hierarchies);
     79        protected void put(Object value, Node node) {
     80                Set<Node> nodes = indexedValues.get(value);
     81                if (nodes == null) {
     82                        nodes = new HashSet<Node>();
     83                        indexedValues.put(value, nodes);
    8484                }
    85                 hierarchies.add(hierarchy);
     85                nodes.add(node);
    8686        }
    8787
     
    9292         * @param hierarchy Indexing hierarchy.
    9393         */
    94         protected void remove(Object value, IndexHierarchy hierarchy) {
    95                 Set<IndexHierarchy> hierarchies = indexedValues.get(value);
    96                 if (hierarchies == null) {
     94        protected void remove(Object value, Node node) {
     95                Set<Node> nodes = indexedValues.get(value);
     96                if (nodes == null) {
    9797                        return;
    9898                }
    99                 hierarchies.remove(hierarchy);
     99                nodes.remove(node);
    100100
    101                 if (hierarchies.isEmpty()) {
     101                if (nodes.isEmpty()) {
    102102                        indexedValues.remove(value);
    103103                }
     
    116116         */
    117117        public boolean contains(Object value) {
    118                 Set<IndexHierarchy> hierarchies = indexedValues.get(value);
    119                 if (hierarchies == null) {
     118                Set<Node> nodes = indexedValues.get(value);
     119                if (nodes == null) {
    120120                        return false;
    121121                }
     
    134134         * @return Entry set.
    135135         */
    136         protected Set<Map.Entry<Object, Set<IndexHierarchy>>> entrySet() {
     136        protected Set<Map.Entry<Object, Set<Node>>> entrySet() {
    137137                return indexedValues.entrySet();
    138138        }
  • src/main/java/de/erichseifert/warp/io/search/indices/FieldIndex.java

    r39730c4 r05b3ea1  
    2727import java.util.Set;
    2828
    29 import de.erichseifert.warp.io.search.IndexHierarchy;
    3029import de.erichseifert.warp.io.search.IndexedProperty;
    3130import de.erichseifert.warp.io.search.ReplayIndexer;
     31import de.erichseifert.warp.io.search.IndexHierarchy.Node;
    3232
    3333/**
     
    5454
    5555        @Override
    56         public void index(IndexHierarchy hierarchy) {
    57                 if (hierarchy == null) {
     56        public void index(Node node) {
     57                if (node == null) {
    5858                        return;
    5959                }
    60                 Object value = getValue(hierarchy);
    61                 put(value, hierarchy);
     60                Object value = getValue(node);
     61                put(value, node);
    6262        }
    6363
    6464        @Override
    65         public void unindex(IndexHierarchy hierarchy) {
    66                 if (hierarchy == null) {
     65        public void unindex(Node node) {
     66                if (node == null) {
    6767                        return;
    6868                }
    69                 Object value = getValue(hierarchy);
    70                 remove(value, hierarchy);
     69                Object value = getValue(node);
     70                remove(value, node);
    7171        }
    7272
    7373        @Override
    74         public boolean isIndexed(IndexHierarchy hierarchy) {
    75                 Object value = getValue(hierarchy);
     74        public boolean isIndexed(Node node) {
     75                Object value = getValue(node);
    7676                return contains(value);
    7777        }
    7878
    7979        @Override
    80         public Set<IndexHierarchy> search(Object query, Range range) {
    81                 Set<IndexHierarchy> results;
     80        public Set<Node> search(Object query, Range range) {
     81                Set<Node> results;
    8282                if (query instanceof Comparable<?>) {
    83                         results = new HashSet<IndexHierarchy>();
    84                         for (Map.Entry<Object, Set<IndexHierarchy>> entry : entrySet()) {
     83                        results = new HashSet<Node>();
     84                        for (Map.Entry<Object, Set<Node>> entry : entrySet()) {
    8585                                Object key = entry.getKey();
    8686                                if (key instanceof Comparable<?>) {
  • src/main/java/de/erichseifert/warp/io/search/indices/FullTextIndex.java

    r39730c4 r05b3ea1  
    2525import java.util.Set;
    2626
    27 import de.erichseifert.warp.io.search.IndexHierarchy;
    2827import de.erichseifert.warp.io.search.IndexedProperty;
    2928import de.erichseifert.warp.io.search.ReplayIndexer;
     29import de.erichseifert.warp.io.search.IndexHierarchy.Node;
    3030
    3131/**
     
    6767
    6868        @Override
    69         public void index(IndexHierarchy hierarchy) {
    70                 if (hierarchy == null) {
     69        public void index(Node node) {
     70                if (node == null) {
    7171                        return;
    7272                }
    73                 Object value = getValue(hierarchy);
     73                Object value = getValue(node);
    7474                String[] normalizedValue = normalize(value.toString());
    7575                for (String part : normalizedValue) {
    76                         put(part, hierarchy);
     76                        put(part, node);
    7777                }
    7878        }
    7979
    8080        @Override
    81         public void unindex(IndexHierarchy hierarchy) {
    82                 if (hierarchy == null) {
     81        public void unindex(Node node) {
     82                if (node == null) {
    8383                        return;
    8484                }
    85                 Object value = getValue(hierarchy);
     85                Object value = getValue(node);
    8686                String[] normalizedValue = normalize(value.toString());
    8787                for (String part : normalizedValue) {
    88                         remove(part, hierarchy);
     88                        remove(part, node);
    8989                }
    9090        }
    9191
    9292        @Override
    93         public boolean isIndexed(IndexHierarchy hierarchy) {
    94                 if (hierarchy == null) {
     93        public boolean isIndexed(Node node) {
     94                if (node == null) {
    9595                        return false;
    9696                }
    9797
    98                 Object value = getValue(hierarchy);
     98                Object value = getValue(node);
    9999                String[] normalizedValue = normalize(value.toString());
    100100                for (String part : normalizedValue) {
     
    123123
    124124        @Override
    125         public Set<IndexHierarchy> search(Object query, Range range) {
    126                 Set<IndexHierarchy> results = new HashSet<IndexHierarchy>();
     125        public Set<Node> search(Object query, Range range) {
     126                Set<Node> results = new HashSet<Node>();
    127127                String[] normalizedValue = normalize(query.toString());
    128128                for (String part : normalizedValue) {
    129                         Set<IndexHierarchy> partResults = get(part);
     129                        Set<Node> partResults = get(part);
    130130                        if (partResults != null) {
    131131                                results.addAll(partResults);
  • src/main/java/de/erichseifert/warp/io/search/indices/Index.java

    r39730c4 r05b3ea1  
    2525import java.util.Set;
    2626
    27 import de.erichseifert.warp.io.search.IndexHierarchy;
     27import de.erichseifert.warp.io.search.IndexHierarchy.Node;
    2828
    2929/**
     
    4949         * @param obj Object to be indexed.
    5050         */
    51         void index(IndexHierarchy hierarchy);
     51        void index(Node node);
    5252        /**
    5353         * Removes the specified object from the index.
    5454         * @param obj Object to be removed from the index.
    5555         */
    56         void unindex(IndexHierarchy hierarchy);
     56        void unindex(Node node);
    5757
    5858        /**
     
    6262         * @return Query results.
    6363         */
    64         Set<IndexHierarchy> search(Object query, Range range);
     64        Set<Node> search(Object query, Range range);
    6565        /**
    6666         * Returns whether the specified object is stored or not stored in this
     
    6969         * @return <code>true</code>, if the object is indexed.
    7070         */
    71         boolean isIndexed(IndexHierarchy hierarchy);
     71        boolean isIndexed(Node node);
    7272
    7373        /**
Note: See TracChangeset for help on using the changeset viewer.