RingBuffer.java

1
package com.renomad.minum.utils;
2
3
import java.lang.reflect.Array;
4
import java.util.Iterator;
5
import java.util.List;
6
import java.util.NoSuchElementException;
7
8
/**
9
 * A minimalist implementation of a ring buffer
10
 * For use with web mechanisms like the multipart body processor
11
 * and the HTML processor.
12
 */
13
public class RingBuffer<T> implements Iterable<T>{
14
15
    /**
16
     * The size of the inner array supporting this class.  Also,
17
     * the most items our RingBuffer can contain.
18
     */
19
    private final int limit;
20
21
    /**
22
     * The last index of the array - just the limit minus 1.
23
     */
24
    private final int lastIndex;
25
26
    /**
27
     * An instance of the class for this generic collection, used to
28
     * help build data structures.
29
     */
30
    private final T[] innerArray;
31
32
    /**
33
     * Index of where we place the next item
34
     */
35
    private int nextIndex;
36
37
    /**
38
     * Build a {@link RingBuffer}
39
     * @param limit the maximum size of the buffer
40
     */
41
    public RingBuffer(int limit, Class<T> clazz) {
42
        this.limit = limit;
43 1 1. <init> : Replaced integer subtraction with addition → KILLED
        this.lastIndex = limit - 1;
44
        @SuppressWarnings("unchecked")
45
        final T[] t = (T[]) Array.newInstance(clazz, limit);
46
        this.innerArray = t;
47
        this.nextIndex = 0;
48
    }
49
50
    /**
51
     * This will move the index forward and
52
     * wrap around at the end.
53
     */
54
    private int incrementIndex(int index) {
55 1 1. incrementIndex : negated conditional → KILLED
        if (index == lastIndex) {
56
            return 0;
57
        } else {
58 2 1. incrementIndex : Replaced integer addition with subtraction → KILLED
2. incrementIndex : replaced int return with 0 for com/renomad/minum/utils/RingBuffer::incrementIndex → KILLED
            return index + 1;
59
        }
60
    }
61
62
    public void add(T item) {
63
        innerArray[nextIndex] = item;
64
        nextIndex = incrementIndex(nextIndex);
65
    }
66
67
    public int getLimit() {
68 1 1. getLimit : replaced int return with 0 for com/renomad/minum/utils/RingBuffer::getLimit → KILLED
        return limit;
69
    }
70
71
    /**
72
     * Returns true if the data in the "myList" parameter is found
73
     * within the RingBuffer.
74
     */
75
    public boolean contains(List<T> myList) {
76 2 1. contains : negated conditional → KILLED
2. contains : negated conditional → KILLED
        if (myList == null || myList.isEmpty()) {
77
            throw new UtilsException("expected a valid non-empty list to search for in the RingBuffer");
78
        }
79 2 1. contains : negated conditional → KILLED
2. contains : changed conditional boundary → KILLED
        for (int i = 0; i < this.limit; i++) {
80 1 1. contains : negated conditional → KILLED
            if (this.containsAt(myList, i)) {
81 1 1. contains : replaced boolean return with false for com/renomad/minum/utils/RingBuffer::contains → KILLED
                return true;
82
            }
83
        }
84 1 1. contains : replaced boolean return with true for com/renomad/minum/utils/RingBuffer::contains → KILLED
        return false;
85
    }
86
87
    /**
88
     * Returns true if the data in the "myList" parameter is found
89
     * within the RingBuffer at the index provided.
90
     */
91
    public boolean containsAt(List<T> myList, int index) {
92 2 1. containsAt : negated conditional → KILLED
2. containsAt : negated conditional → KILLED
        if (myList == null || myList.isEmpty()) {
93
            throw new UtilsException("expected a valid non-empty list to search for in the RingBuffer");
94
        }
95 4 1. containsAt : changed conditional boundary → KILLED
2. containsAt : changed conditional boundary → KILLED
3. containsAt : negated conditional → KILLED
4. containsAt : negated conditional → KILLED
        if (index > lastIndex || index < 0) {
96
            throw new UtilsException("expected an index greater than zero and less-than-or-equal to the last index of the buffer (the limit minus one)");
97
        }
98
        int i = 0;
99
        int myListIndex = 0;
100 1 1. containsAt : Replaced integer subtraction with addition → KILLED
        int myListLastIndex = myList.size() - 1;
101
        boolean comparing = false;
102
        var iterator = this.iterator();
103 1 1. containsAt : negated conditional → KILLED
        while (iterator.hasNext()) {
104
            var value = iterator.next();
105 1 1. containsAt : negated conditional → KILLED
            if (i == index) {
106
                comparing = true;
107
            }
108
109 1 1. containsAt : negated conditional → KILLED
            if (comparing) {
110 1 1. containsAt : negated conditional → KILLED
                if (! myList.get(myListIndex).equals(value)) {
111 1 1. containsAt : replaced boolean return with true for com/renomad/minum/utils/RingBuffer::containsAt → KILLED
                    return false;
112
                }
113 1 1. containsAt : negated conditional → KILLED
                if (myListIndex == myListLastIndex) {
114 1 1. containsAt : replaced boolean return with false for com/renomad/minum/utils/RingBuffer::containsAt → KILLED
                    return true;
115
                }
116 1 1. containsAt : Changed increment from 1 to -1 → KILLED
                myListIndex += 1;
117
            }
118
119 1 1. containsAt : Changed increment from 1 to -1 → KILLED
            i += 1;
120
        }
121 1 1. containsAt : replaced boolean return with true for com/renomad/minum/utils/RingBuffer::containsAt → KILLED
        return false;
122
    }
123
124
    @Override
125
    public Iterator<T> iterator() {
126 1 1. iterator : replaced return value with null for com/renomad/minum/utils/RingBuffer::iterator → KILLED
        return new Iterator<>() {
127
128
            /**
129
             * As we loop through the buffer, we have to use a similar
130
             * technique to the "nextIndex" - wrapping around when we
131
             * hit the end
132
             */
133
            int iteratorIndex = nextIndex;
134
            /**
135
             * We'll count as we read values, stopping when we've read every slot.
136
             */
137
            int count = 0;
138
139
            @Override
140
            public boolean hasNext() {
141 3 1. hasNext : changed conditional boundary → KILLED
2. hasNext : negated conditional → KILLED
3. hasNext : replaced boolean return with true for com/renomad/minum/utils/RingBuffer$1::hasNext → KILLED
                return count < limit;
142
            }
143
144
            @Override
145
            public T next() {
146 1 1. next : negated conditional → KILLED
                if (!hasNext()) {
147
                    throw new NoSuchElementException();
148
                }
149
                var result = innerArray[iteratorIndex];
150
                iteratorIndex = incrementIndex(iteratorIndex);
151 1 1. next : Replaced integer addition with subtraction → KILLED
                count += 1;
152 1 1. next : replaced return value with null for com/renomad/minum/utils/RingBuffer$1::next → KILLED
                return result;
153
            }
154
        };
155
    }
156
157
    /**
158
     * Returns the value at the slot pointed to by the "nextIndex".  Note that
159
     * this will be null at first while the array starts to get filled.
160
     */
161
    public T atNextIndex() {
162 1 1. atNextIndex : replaced return value with null for com/renomad/minum/utils/RingBuffer::atNextIndex → KILLED
        return innerArray[nextIndex];
163
    }
164
165
}

Mutations

43

1.1
Location : <init>
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
Replaced integer subtraction with addition → KILLED

55

1.1
Location : incrementIndex
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

58

1.1
Location : incrementIndex
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
Replaced integer addition with subtraction → KILLED

2.2
Location : incrementIndex
Killed by : com.renomad.minum.utils.RingBufferTests
replaced int return with 0 for com/renomad/minum/utils/RingBuffer::incrementIndex → KILLED

68

1.1
Location : getLimit
Killed by : com.renomad.minum.web.BoundaryBugTest
replaced int return with 0 for com/renomad/minum/utils/RingBuffer::getLimit → KILLED

76

1.1
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

2.2
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

79

1.1
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

2.2
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
changed conditional boundary → KILLED

80

1.1
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

81

1.1
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
replaced boolean return with false for com/renomad/minum/utils/RingBuffer::contains → KILLED

84

1.1
Location : contains
Killed by : com.renomad.minum.utils.RingBufferTests
replaced boolean return with true for com/renomad/minum/utils/RingBuffer::contains → KILLED

92

1.1
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
negated conditional → KILLED

2.2
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
negated conditional → KILLED

95

1.1
Location : containsAt
Killed by : com.renomad.minum.web.BoundaryBugTest
changed conditional boundary → KILLED

2.2
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
changed conditional boundary → KILLED

3.3
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
negated conditional → KILLED

4.4
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
negated conditional → KILLED

100

1.1
Location : containsAt
Killed by : com.renomad.minum.utils.RingBufferTests
Replaced integer subtraction with addition → KILLED

103

1.1
Location : containsAt
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

105

1.1
Location : containsAt
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

109

1.1
Location : containsAt
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

110

1.1
Location : containsAt
Killed by : com.renomad.minum.web.BoundaryBugTest
negated conditional → KILLED

111

1.1
Location : containsAt
Killed by : com.renomad.minum.web.BoundaryBugTest
replaced boolean return with true for com/renomad/minum/utils/RingBuffer::containsAt → KILLED

113

1.1
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
negated conditional → KILLED

114

1.1
Location : containsAt
Killed by : com.renomad.minum.utils.RingBufferTests
replaced boolean return with false for com/renomad/minum/utils/RingBuffer::containsAt → KILLED

116

1.1
Location : containsAt
Killed by : com.renomad.minum.web.BoundaryBugTest
Changed increment from 1 to -1 → KILLED

119

1.1
Location : containsAt
Killed by : com.renomad.minum.utils.RingBufferTests
Changed increment from 1 to -1 → KILLED

121

1.1
Location : containsAt
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
replaced boolean return with true for com/renomad/minum/utils/RingBuffer::containsAt → KILLED

126

1.1
Location : iterator
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
replaced return value with null for com/renomad/minum/utils/RingBuffer::iterator → KILLED

141

1.1
Location : hasNext
Killed by : com.renomad.minum.utils.RingBufferTests
changed conditional boundary → KILLED

2.2
Location : hasNext
Killed by : com.renomad.minum.utils.RingBufferTests
negated conditional → KILLED

3.3
Location : hasNext
Killed by : com.renomad.minum.utils.RingBufferTests
replaced boolean return with true for com/renomad/minum/utils/RingBuffer$1::hasNext → KILLED

146

1.1
Location : next
Killed by : com.renomad.minum.BugExposureTests.test_RingBuffer_ContainsAt_PatternExtendsBeyondBuffer(com.renomad.minum.BugExposureTests)
negated conditional → KILLED

151

1.1
Location : next
Killed by : com.renomad.minum.utils.RingBufferTests
Replaced integer addition with subtraction → KILLED

152

1.1
Location : next
Killed by : com.renomad.minum.utils.RingBufferTests
replaced return value with null for com/renomad/minum/utils/RingBuffer$1::next → KILLED

162

1.1
Location : atNextIndex
Killed by : com.renomad.minum.web.BoundaryBugTest
replaced return value with null for com/renomad/minum/utils/RingBuffer::atNextIndex → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0