001/*
002 * ModeShape (http://www.modeshape.org)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *       http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.modeshape.common.collection;
017
018import java.util.AbstractCollection;
019import java.util.AbstractMap;
020import java.util.AbstractSequentialList;
021import java.util.AbstractSet;
022import java.util.ArrayList;
023import java.util.Collection;
024import java.util.HashMap;
025import java.util.HashSet;
026import java.util.Iterator;
027import java.util.LinkedList;
028import java.util.List;
029import java.util.ListIterator;
030import java.util.Map;
031import java.util.NoSuchElementException;
032import java.util.Set;
033import java.util.concurrent.atomic.AtomicInteger;
034import org.modeshape.common.util.ObjectUtil;
035
036/**
037 * A {@link Multimap} implementation that uses an {@link LinkedList} to store the values associated with a key. This
038 * implementation allows duplicate values for a key, maintains the insertion-order of the {@link #get(Object) values for each key}
039 * , and maintains the insertion order of all {@link #entries() key-value pairs}.
040 * 
041 * @param <K> the key type
042 * @param <V> the value type
043 */
044public final class LinkedListMultimap<K, V> implements ListMultimap<K, V> {
045
046    /**
047     * Creates a new, empty {@code LinkedListMultimap} with the default initial capacity.
048     * 
049     * @param <K> the key type
050     * @param <V> the value type
051     * @return the new linked-list multimap; never null
052     */
053    public static <K, V> LinkedListMultimap<K, V> create() {
054        return new LinkedListMultimap<K, V>();
055    }
056
057    protected static final class Entry<K, V> {
058        final K key;
059        V value;
060        Entry<K, V> nextWithKey;
061        Entry<K, V> previousWithKey;
062        Entry<K, V> next;
063        Entry<K, V> previous;
064
065        protected Entry( K key,
066                         V value ) {
067            this.key = key;
068            this.value = value;
069        }
070
071        /**
072         * {@inheritDoc}
073         * 
074         * @see java.lang.Object#toString()
075         */
076        @Override
077        public String toString() {
078            return "[" + key + "=" + value + "]";
079        }
080    }
081
082    protected Entry<K, V> firstEntry;
083    protected Entry<K, V> lastEntry;
084    protected int length;
085    protected final Map<K, AtomicInteger> numberOfEntriesForKey;
086    protected final Map<K, Entry<K, V>> firstEntryWithKey;
087    protected final Map<K, Entry<K, V>> lastEntryWithKey;
088
089    private transient Map<K, Collection<V>> mapView;
090
091    protected LinkedListMultimap() {
092        this.firstEntryWithKey = new HashMap<K, Entry<K, V>>();
093        this.lastEntryWithKey = new HashMap<K, Entry<K, V>>();
094        this.numberOfEntriesForKey = new HashMap<K, AtomicInteger>();
095    }
096
097    @Override
098    public void clear() {
099        length = 0;
100        firstEntryWithKey.clear();
101        lastEntryWithKey.clear();
102    }
103
104    @Override
105    public int size() {
106        return length;
107    }
108
109    @Override
110    public boolean isEmpty() {
111        return length == 0;
112    }
113
114    @Override
115    public boolean containsKey( K key ) {
116        return firstEntryWithKey.containsKey(key);
117    }
118
119    @Override
120    public boolean containsEntry( Object key,
121                                  Object value ) {
122        @SuppressWarnings( "unchecked" )
123        ValueIterator values = new ValueIterator((K)key);
124        while (values.hasNext()) {
125            if (ObjectUtil.isEqualWithNulls(values.next(), value)) return true;
126        }
127        return false;
128    }
129
130    @Override
131    public boolean containsValue( Object value ) {
132        EntryIterator entries = new EntryIterator();
133        while (entries.hasNext()) {
134            if (ObjectUtil.isEqualWithNulls(entries.next().value, value)) return true;
135        }
136        return false;
137    }
138
139    @Override
140    public List<V> get( final K key ) {
141        return new AbstractSequentialList<V>() {
142            @Override
143            public int size() {
144                return currentCountFor(key);
145            }
146
147            @Override
148            public ListIterator<V> listIterator( int index ) {
149                return new ValueIterator(key, index);
150            }
151        };
152    }
153
154    @Override
155    public boolean put( K key,
156                        V value ) {
157        addEntryFor(key, value);
158        return true;
159    }
160
161    @Override
162    public boolean remove( K key,
163                           V value ) {
164        // Find the entry with the value ...
165        ValueIterator values = new ValueIterator(key);
166        while (values.hasNext()) {
167            if (ObjectUtil.isEqualWithNulls(values.next(), value)) {
168                values.remove();
169                return true;
170            }
171        }
172        return false;
173    }
174
175    @Override
176    public Collection<V> removeAll( K key ) {
177        // Find the entries with the value ...
178        List<V> result = new ArrayList<V>(currentCountFor(key));
179        ValueIterator values = new ValueIterator(key);
180        while (values.hasNext()) {
181            result.add(values.next());
182            values.remove();
183        }
184        return result;
185    }
186
187    @Override
188    public Collection<Map.Entry<K, V>> entries() {
189        return new AbstractCollection<Map.Entry<K, V>>() {
190            @Override
191            public int size() {
192                return length;
193            }
194
195            @Override
196            public Iterator<Map.Entry<K, V>> iterator() {
197                return new Iterator<Map.Entry<K, V>>() {
198                    private final EntryIterator iter = new EntryIterator();
199
200                    @Override
201                    public boolean hasNext() {
202                        return iter.hasNext();
203                    }
204
205                    @Override
206                    public Map.Entry<K, V> next() {
207                        Entry<K, V> next = iter.next();
208                        return new ImmutableMapEntry<K, V>(next.key, next.value);
209                    }
210
211                    @Override
212                    public void remove() {
213                        iter.remove();
214                    }
215                };
216            }
217        };
218    }
219
220    @Override
221    public Set<K> keySet() {
222        return new AbstractSet<K>() {
223            @Override
224            public int size() {
225                return numberOfEntriesForKey.size();
226            }
227
228            @Override
229            public Iterator<K> iterator() {
230                return new KeyIterator();
231            }
232        };
233    }
234
235    @Override
236    public Collection<V> values() {
237        return new AbstractCollection<V>() {
238            @Override
239            public int size() {
240                return length;
241            }
242
243            @Override
244            public Iterator<V> iterator() {
245                return new Iterator<V>() {
246                    private final EntryIterator iter = new EntryIterator();
247
248                    @Override
249                    public boolean hasNext() {
250                        return iter.hasNext();
251                    }
252
253                    @Override
254                    public V next() {
255                        Entry<K, V> next = iter.next();
256                        return next.value;
257                    }
258
259                    @Override
260                    public void remove() {
261                        iter.remove();
262                    }
263                };
264            }
265        };
266    }
267
268    @Override
269    public Map<K, Collection<V>> asMap() {
270        if (mapView == null) mapView = new MapView();
271        return mapView;
272    }
273
274    protected class MapView extends AbstractMap<K, Collection<V>> {
275
276        private Set<Map.Entry<K, Collection<V>>> entries;
277
278        @Override
279        public Set<Map.Entry<K, Collection<V>>> entrySet() {
280            if (entries == null) entries = new MapEntries();
281            return entries;
282        }
283    }
284
285    protected class MapEntries extends AbstractSet<Map.Entry<K, Collection<V>>> {
286        @Override
287        public int size() {
288            return length;
289        }
290
291        @Override
292        public Iterator<Map.Entry<K, Collection<V>>> iterator() {
293            return new Iterator<Map.Entry<K, Collection<V>>>() {
294                private KeyIterator iter = new KeyIterator();
295
296                @Override
297                public boolean hasNext() {
298                    return iter.hasNext();
299                }
300
301                @Override
302                public Map.Entry<K, Collection<V>> next() {
303                    final K nextKey = iter.next();
304                    return new ImmutableMapEntry<K, Collection<V>>(nextKey, null) {
305                        @Override
306                        public Collection<V> getValue() {
307                            return get(nextKey);
308                        }
309                    };
310                }
311
312                @Override
313                public void remove() {
314                    iter.remove();
315                }
316            };
317        }
318    }
319
320    @Override
321    public int hashCode() {
322        return asMap().hashCode();
323    }
324
325    @Override
326    public boolean equals( Object obj ) {
327        if (obj == this) return true;
328        if (obj instanceof Multimap) {
329            Multimap<?, ?> that = (Multimap<?, ?>)obj;
330            return this.asMap().equals(that.asMap());
331        }
332        return false;
333    }
334
335    @Override
336    public String toString() {
337        return asMap().toString();
338    }
339
340    protected int incrementEntryCountFor( K key ) {
341        AtomicInteger count = numberOfEntriesForKey.get(key);
342        if (count == null) {
343            count = new AtomicInteger(0);
344            numberOfEntriesForKey.put(key, count);
345        }
346        ++length;
347        return count.incrementAndGet();
348    }
349
350    protected int decrementEntryCountFor( K key ) {
351        AtomicInteger count = numberOfEntriesForKey.get(key);
352        assert count != null;
353        int result = count.decrementAndGet();
354        if (result == 0) numberOfEntriesForKey.remove(key);
355        --length;
356        return result;
357    }
358
359    protected int currentCountFor( K key ) {
360        AtomicInteger count = numberOfEntriesForKey.get(key);
361        return count != null ? count.get() : 0;
362    }
363
364    protected Entry<K, V> addEntryFor( K key,
365                                       V value ) {
366        Entry<K, V> entry = new Entry<K, V>(key, value);
367        if (firstEntry == null) {
368            assert length == 0;
369            // This is the first entry ...
370            firstEntry = entry;
371            firstEntryWithKey.put(key, entry);
372        } else {
373            // Add this entry to the end ...
374            lastEntry.next = entry;
375            entry.previous = lastEntry;
376            // Find the last entry with this key ...
377            Entry<K, V> lastWithKey = lastEntryWithKey.get(key);
378            if (lastWithKey == null) {
379                // This is the first entry for this key ...
380                firstEntryWithKey.put(key, entry);
381            }
382        }
383
384        // This entry is always the last entry ...
385        Entry<K, V> previousLastWithKey = lastEntryWithKey.put(key, entry);
386        if (previousLastWithKey != null) {
387            previousLastWithKey.nextWithKey = entry;
388            entry.previousWithKey = previousLastWithKey;
389        }
390        lastEntry = entry;
391        incrementEntryCountFor(key);
392        return entry;
393    }
394
395    protected Entry<K, V> insertEntryBefore( K key,
396                                             V value,
397                                             Entry<K, V> nextEntryWithKey ) {
398        if (nextEntryWithKey == null) return addEntryFor(key, value);
399
400        // Otherwise the new entry will lever be last ...
401        Entry<K, V> entry = new Entry<K, V>(key, value);
402        assert firstEntry != null;
403        assert length != 0;
404        // Set the entry's references ...
405        entry.next = nextEntryWithKey;
406        entry.nextWithKey = nextEntryWithKey;
407        entry.previous = nextEntryWithKey.previous;
408        entry.previousWithKey = nextEntryWithKey.previousWithKey;
409        // Set the reference from the entry that WAS before the next entry ...
410        if (nextEntryWithKey.previousWithKey != null) {
411            // This will NOT be the first entry for this key ...
412            nextEntryWithKey.previousWithKey.nextWithKey = entry;
413        } else {
414            // This will be the first entry for this key ...
415            firstEntryWithKey.put(key, entry);
416        }
417        if (nextEntryWithKey.previous != null) {
418            // This will NOT be the first entry ...
419            nextEntryWithKey.previous.next = entry;
420        } else {
421            // This will be the first entry ...
422            firstEntry = entry;
423        }
424        // Set the reference from the next entry ...
425        nextEntryWithKey.previousWithKey = entry;
426        nextEntryWithKey.previous = entry;
427        incrementEntryCountFor(key);
428        return entry;
429    }
430
431    protected void removeEntry( Entry<K, V> entry ) {
432        if (entry.previous == null) {
433            // The entry was the first ...
434            assert firstEntry == entry;
435            firstEntry = entry.next;
436        } else {
437            // Just a normal entry that is not at the front ...
438            entry.previous.next = entry.next;
439        }
440        if (entry.next == null) {
441            // The entry was the last ...
442            assert lastEntry == entry;
443            lastEntry = entry.previous;
444        } else {
445            // Just a normal entry that is not at the ed ...
446            entry.next.previous = entry.previous;
447        }
448        if (entry.previousWithKey != null) {
449            entry.previousWithKey.nextWithKey = entry.nextWithKey;
450        } else if (entry.nextWithKey != null) {
451            // We're removing the first entry with the key, and there is a next entry with the key ..
452            firstEntryWithKey.put(entry.key, entry.nextWithKey);
453        } else {
454            // We're removing the first and only entry with the key ...
455            firstEntryWithKey.remove(entry.key);
456        }
457        if (entry.nextWithKey != null) {
458            entry.nextWithKey.previousWithKey = entry.previousWithKey;
459        } else if (entry.previousWithKey != null) {
460            // We're removing the last entry with the key, and there is a previoius entry with the key ..
461            lastEntryWithKey.put(entry.key, entry.previousWithKey);
462        } else {
463            // We're removing the last and only entry with the key ...
464            lastEntryWithKey.remove(entry.key);
465        }
466        decrementEntryCountFor(entry.key);
467    }
468
469    protected void isValid( Entry<K, V> entry ) {
470        if (entry == null) throw new NoSuchElementException();
471    }
472
473    protected class EntryIterator implements Iterator<Entry<K, V>> {
474        private Entry<K, V> nextEntry;
475        private Entry<K, V> currentEntry;
476
477        protected EntryIterator() {
478            nextEntry = firstEntry;
479        }
480
481        protected EntryIterator( Entry<K, V> first ) {
482            nextEntry = first;
483        }
484
485        @Override
486        public boolean hasNext() {
487            return nextEntry != null;
488        }
489
490        @Override
491        public Entry<K, V> next() {
492            isValid(nextEntry);
493            currentEntry = nextEntry;
494            nextEntry = nextEntry.next;
495            return currentEntry;
496        }
497
498        @Override
499        public void remove() {
500            if (currentEntry == null) throw new IllegalStateException();
501            removeEntry(currentEntry);
502            currentEntry = null;
503        }
504    }
505
506    protected class ValueIterator implements ListIterator<V> {
507        private Entry<K, V> previous;
508        private Entry<K, V> current;
509        private Entry<K, V> next;
510        private int nextIndex;
511        private final K key;
512
513        protected ValueIterator( K key ) {
514            this.key = key;
515            next = firstEntryWithKey.get(key);
516            nextIndex = 0;
517        }
518
519        protected ValueIterator( K key,
520                                 int index ) {
521            this.key = key;
522            int count = currentCountFor(key);
523            if (index > count / 2) {
524                // The index is closer to the end, so start at the end ..
525                previous = lastEntryWithKey.get(key);
526                nextIndex = count;
527                while (index++ < count) {
528                    previous();
529                }
530            } else {
531                // The index is closer to the front, so start at the front ...
532                next = firstEntryWithKey.get(key);
533                nextIndex = 0;
534                while (index-- > 0) {
535                    next();
536                }
537            }
538        }
539
540        @Override
541        public boolean hasNext() {
542            return next != null;
543        }
544
545        @Override
546        public V next() {
547            isValid(next);
548            current = next;
549            previous = next;
550            next = current.nextWithKey;
551            ++nextIndex;
552            return current.value;
553        }
554
555        @Override
556        public int nextIndex() {
557            return nextIndex;
558        }
559
560        @Override
561        public boolean hasPrevious() {
562            return previous != null;
563        }
564
565        @Override
566        public V previous() {
567            isValid(previous);
568            current = previous;
569            next = previous;
570            previous = current.previousWithKey;
571            --nextIndex;
572            return current.value;
573        }
574
575        @Override
576        public int previousIndex() {
577            return nextIndex - 1;
578        }
579
580        @Override
581        public void remove() {
582            if (current == null) throw new IllegalStateException();
583            if (current != next) {
584                // removing next element
585                previous = current.previousWithKey;
586                nextIndex--;
587            } else {
588                next = current.nextWithKey;
589            }
590            removeEntry(current);
591            current = null;
592        }
593
594        @Override
595        public void add( V value ) {
596            if (next == null) {
597                previous = addEntryFor(key, value);
598            } else {
599                previous = insertEntryBefore(key, value, next);
600            }
601            nextIndex++;
602            current = null;
603        }
604
605        @Override
606        public void set( V value ) {
607            if (current == null) throw new IllegalStateException();
608            current.value = value;
609        }
610    }
611
612    protected class KeyIterator implements Iterator<K> {
613        private final Set<K> seen = new HashSet<K>();
614        private Entry<K, V> next = firstEntry;
615        private Entry<K, V> current = null;
616
617        @Override
618        public boolean hasNext() {
619            return next != null;
620        }
621
622        @Override
623        public K next() {
624            if (next == null) throw new NoSuchElementException();
625            current = next;
626            seen.add(current.key);
627            do {
628                next = next.next;
629            } while (next != null && !seen.add(next.key));
630            return current.key;
631        }
632
633        @Override
634        public void remove() {
635            if (current == null) throw new NoSuchElementException();
636            removeAll(current.key);
637            current = null;
638        }
639    }
640
641}