• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LearnLib / learnlib / 6673301747

27 Oct 2023 11:46PM UTC coverage: 91.986% (-1.3%) from 93.327%
6673301747

push

github

mtf90
merge the release and sign-artifacts profiles

10984 of 11941 relevant lines covered (91.99%)

1.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.9
/filters/reuse/src/main/java/de/learnlib/filter/reuse/tree/BoundedDeque.java
1
/* Copyright (C) 2013-2023 TU Dortmund
2
 * This file is part of LearnLib, http://www.learnlib.de/.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package de.learnlib.filter.reuse.tree;
17

18
import java.util.AbstractCollection;
19
import java.util.ArrayDeque;
20
import java.util.Deque;
21
import java.util.Iterator;
22

23
import org.checkerframework.checker.nullness.qual.Nullable;
24

25
/**
26
 * A generic deque-derived container which transparently acts <i>either</i> as a stack <i>or</i> a queue, and optionally
27
 * a capacity restriction with a configurable policy which element is evicted (or reject) if the maximum capacity is
28
 * reached.
29
 * <p>
30
 * <b>Note:</b> Like {@link ArrayDeque}, this deque implementation is not thread-safe. Concurrent access by multiple
31
 * threads requires explicit synchronization.
32
 *
33
 * @param <E>
34
 *         element type
35
 */
36
public class BoundedDeque<E> extends AbstractCollection<E> {
37

38
    private final EvictPolicy evictPolicy;
39
    private final AccessPolicy accessPolicy;
40
    private final int capacity;
41
    private final Deque<E> deque;
42

43
    /**
44
     * Constructor. Creates an unbounded deque with the given access policy.
45
     *
46
     * @param accessPolicy
47
     *         whether this deque acts as a stack or a queue
48
     */
49
    public BoundedDeque(AccessPolicy accessPolicy) {
50
        this(-1, accessPolicy, EvictPolicy.EVICT_OLDEST); // policy does not matter
×
51
    }
×
52

53
    /**
54
     * Constructor. Creates a possibly capacity-restricted deque with the given access policy.
55
     *
56
     * @param capacity
57
     *         the maximum capacity of this deque. A value less than or equal to 0 means unbounded
58
     * @param accessPolicy
59
     *         whether this deque acts as a stack or a queue
60
     * @param evictPolicy
61
     *         which elements to remove if the maximum capacity is reached. If the capacity is unbounded, this parameter
62
     *         has no effect
63
     */
64
    public BoundedDeque(int capacity, AccessPolicy accessPolicy, EvictPolicy evictPolicy) {
2✔
65
        if (capacity <= 0) {
2✔
66
            this.deque = new ArrayDeque<>(); // unbounded, default capacity
2✔
67
        } else {
68
            this.deque = new ArrayDeque<>(capacity);
×
69
        }
70
        this.capacity = capacity;
2✔
71
        this.accessPolicy = accessPolicy;
2✔
72
        this.evictPolicy = evictPolicy;
2✔
73
    }
2✔
74

75
    /**
76
     * Inserts an element into the deque, and returns the one that had to be evicted in case of a capacity violation.
77
     *
78
     * @param element
79
     *         the element to insert
80
     *
81
     * @return the evicted element, {@code null} if the maximum capacity has not been reached
82
     */
83
    public @Nullable E insert(E element) {
84
        E evicted = null;
2✔
85
        if (size() >= capacity) {
2✔
86
            if (evictPolicy == EvictPolicy.REJECT_NEW) {
2✔
87
                // reject the new element
88
                return element;
×
89
            }
90
            // Evict first, so we do not need to resize
91
            evicted = evict();
2✔
92
        }
93
        deque.offerLast(element);
2✔
94
        return evicted;
2✔
95
    }
96

97
    /**
98
     * Evicts an element, depending on the configured {@link EvictPolicy}.
99
     *
100
     * @return the evicted element
101
     */
102
    private E evict() {
103
        switch (evictPolicy) {
2✔
104
            case EVICT_OLDEST:
105
                return deque.pollFirst();
2✔
106
            case EVICT_NEWEST:
107
                return deque.pollLast();
×
108
            default:
109
                throw new IllegalStateException("Illegal evict policy: " + evictPolicy);
×
110
        }
111
    }
112

113
    /**
114
     * Retrieves and remove the top-most element, i.e., the element that is either the top of the stack or the head of
115
     * the queue, depending on the configured {@link AccessPolicy}.
116
     *
117
     * @return the top-most element of the container
118
     */
119
    public E retrieve() {
120
        switch (accessPolicy) {
2✔
121
            case LIFO:
122
                return deque.pollLast();
2✔
123
            case FIFO:
124
                return deque.pollFirst();
×
125
            default:
126
                throw new IllegalStateException("Illegal evict policy: " + evictPolicy);
×
127
        }
128
    }
129

130
    /**
131
     * Retrieves, but does not remove the top-most element, i.e., the element that is either the top of the stack or the
132
     * head of the queue, depending on the configured {@link AccessPolicy}.
133
     *
134
     * @return the top-most element of the container
135
     */
136
    public E peek() {
137
        switch (accessPolicy) {
×
138
            case LIFO:
139
                return deque.peekLast();
×
140
            case FIFO:
141
                return deque.peekFirst();
×
142
            default:
143
                throw new IllegalStateException("Illegal evict policy: " + evictPolicy);
×
144
        }
145
    }
146

147
    /**
148
     * Retrieves whether capacity restriction is in effect.
149
     *
150
     * @return {@code true} if the capacity is restricted, {@code false} otherwise
151
     */
152
    public boolean isBounded() {
153
        return capacity > 0;
×
154
    }
155

156
    @Override
157
    public Iterator<E> iterator() {
158
        return deque.iterator();
×
159
    }
160

161
    @Override
162
    public int size() {
163
        return deque.size();
2✔
164
    }
165

166
    @Override
167
    public boolean isEmpty() {
168
        return deque.isEmpty();
2✔
169
    }
170

171
    @Override
172
    public void clear() {
173
        deque.clear();
×
174
    }
×
175

176
    /**
177
     * The policy which determines in which order elements are accessed.
178
     */
179
    public enum AccessPolicy {
2✔
180
        /**
181
         * Last-in first-out. This deque will then act as a <i>stack</i>.
182
         */
183
        LIFO,
2✔
184
        /**
185
         * First-in first-out. This deque will then act as a <i>queue</i>.
186
         */
187
        FIFO
2✔
188
    }
189

190
    /**
191
     * The policy which determines in which order elements are removed if the maximum capacity is reached.
192
     */
193
    public enum EvictPolicy {
2✔
194
        /**
195
         * Evict the oldest element, i.e., the one at the head of the queue/bottom of the stack.
196
         */
197
        EVICT_OLDEST,
2✔
198
        /**
199
         * Reject the element that is about to be inserted.
200
         */
201
        REJECT_NEW,
2✔
202
        /**
203
         * Evict the newest element, that is already *in* the queue (i.e., in any case inserts the new element).
204
         */
205
        EVICT_NEWEST
2✔
206
    }
207

208
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc