1/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mail.utils;
19
20import com.google.common.collect.Lists;
21import com.google.common.collect.Maps;
22
23import java.util.Deque;
24import java.util.Map;
25
26/**
27 * A Map of Deques. Each entry at key K has a deque of values V.
28 *
29 */
30public class DequeMap<K, V> {
31
32    public interface Visitor<V> {
33        void visit(V item);
34    }
35
36    private final Map<K, Deque<V>> mMap = Maps.newHashMap();
37
38    /**
39     * Add a value V to the deque stored under key K.
40     *
41     */
42    public void add(K key, V item) {
43        Deque<V> pile = mMap.get(key);
44        if (pile == null) {
45            pile = Lists.newLinkedList();
46            mMap.put(key, pile);
47        }
48        pile.add(item);
49    }
50
51    /**
52     * Removes and returns the first value V from the deque of Vs for key K, or null if no such Vs
53     * exist.
54     *
55     * @see Deque#poll()
56     *
57     * @param key
58     * @return a V, or null
59     */
60    public V poll(K key) {
61        final Deque<V> pile = mMap.get(key);
62        if (pile == null) {
63            return null;
64        }
65        return pile.poll();
66    }
67
68    /**
69     * Returns, but does not remove, the first value V from the deque of Vs for key K, or null if
70     * no such Vs exist.
71     *
72     * @see Deque#peek()
73     *
74     * @param key
75     * @return a V, or null
76     */
77    public V peek(K key) {
78        final Deque<V> pile = mMap.get(key);
79        if (pile == null) {
80            return null;
81        }
82        return pile.peek();
83    }
84
85    public void clear() {
86        mMap.clear();
87    }
88
89    /**
90     * Allows a {@link Visitor} to operate on each value V in this structure, irrespective of each
91     * value's key. Modifying this map during iteration is not supported. Iteration order is not
92     * guaranteed.
93     *
94     * @param visitor
95     */
96    // An iterator would also suffice, but this is easier to write and understand.
97    public void visitAll(Visitor<V> visitor) {
98        for (Map.Entry<K, Deque<V>> entry : mMap.entrySet()) {
99            for (V item : entry.getValue()) {
100                visitor.visit(item);
101            }
102        }
103    }
104
105}
106