FrequencyTrieBuilders.java

1
/*******************************************************************************
2
 * Copyright (C) 2026, Leo Galambos
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 *
11
 * 2. Redistributions in binary form must reproduce the above copyright notice,
12
 *    this list of conditions and the following disclaimer in the documentation
13
 *    and/or other materials provided with the distribution.
14
 *
15
 * 3. Neither the name of the copyright holder nor the names of its contributors
16
 *    may be used to endorse or promote products derived from this software
17
 *    without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
 * POSSIBILITY OF SUCH DAMAGE.
30
 ******************************************************************************/
31
package org.egothor.stemmer;
32
33
import java.util.HashSet;
34
import java.util.IdentityHashMap;
35
import java.util.Map;
36
import java.util.Objects;
37
import java.util.Set;
38
import java.util.function.Function;
39
import java.util.function.IntFunction;
40
import java.util.logging.Level;
41
import java.util.logging.Logger;
42
43
import org.egothor.stemmer.trie.CompiledNode;
44
45
/**
46
 * Factory utilities related to {@link FrequencyTrie.Builder}.
47
 *
48
 * <p>
49
 * This helper reconstructs writable builders from compiled read-only tries. The
50
 * reconstruction preserves the semantics and local counts of the compiled trie
51
 * as currently stored, which makes it suitable for subsequent modifications
52
 * followed by recompilation.
53
 *
54
 * <p>
55
 * Reconstruction operates on the compiled form. Therefore, if the compiled trie
56
 * was produced using a reduction mode that merged semantically equivalent
57
 * subtrees, the recreated builder reflects that reduced compiled state rather
58
 * than the exact original unreduced insertion history.
59
 */
60
public final class FrequencyTrieBuilders {
61
62
    /**
63
     * Logger of this class.
64
     */
65
    private static final Logger LOGGER = Logger.getLogger(FrequencyTrieBuilders.class.getName());
66
67
    /**
68
     * Utility class.
69
     */
70
    private FrequencyTrieBuilders() {
71
        throw new AssertionError("No instances.");
72
    }
73
74
    /**
75
     * Reconstructs a new writable builder from a compiled read-only trie.
76
     *
77
     * <p>
78
     * The returned builder contains the same key-local value counts as the supplied
79
     * compiled trie. Callers may continue modifying the returned builder and then
80
     * compile a new {@link FrequencyTrie} instance.
81
     *
82
     * @param source            source compiled trie
83
     * @param arrayFactory      array factory for the reconstructed builder
84
     * @param reductionSettings reduction settings to associate with the new builder
85
     * @param <V>               value type
86
     * @return reconstructed writable builder
87
     * @throws NullPointerException if any argument is {@code null}
88
     */
89
    public static <V> FrequencyTrie.Builder<V> copyOf(final FrequencyTrie<V> source,
90
            final IntFunction<V[]> arrayFactory, final ReductionSettings reductionSettings) {
91
        Objects.requireNonNull(source, "source");
92
        Objects.requireNonNull(arrayFactory, "arrayFactory");
93
        Objects.requireNonNull(reductionSettings, "reductionSettings");
94
95
        final FrequencyTrie.Builder<V> builder = new FrequencyTrie.Builder<>(arrayFactory, reductionSettings,
96
                source.traversalDirection(), source.metadata().caseProcessingMode(),
97
                source.metadata().diacriticProcessingMode());
98
        final StringBuilder keyBuilder = new StringBuilder(64);
99
100 1 1. copyOf : removed call to org/egothor/stemmer/FrequencyTrieBuilders::copyNode → KILLED
        copyNode(source.root(), keyBuilder, builder, source.traversalDirection());
101
102
        LOGGER.log(Level.FINE, "Reconstructed writable builder from compiled trie.");
103 1 1. copyOf : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::copyOf → KILLED
        return builder;
104
    }
105
106
    /**
107
     * Reconstructs a new writable builder from a compiled read-only trie using
108
     * default settings for the supplied reduction mode.
109
     *
110
     * @param source        source compiled trie
111
     * @param arrayFactory  array factory for the reconstructed builder
112
     * @param reductionMode reduction mode to associate with the new builder
113
     * @param <V>           value type
114
     * @return reconstructed writable builder
115
     * @throws NullPointerException if any argument is {@code null}
116
     */
117
    public static <V> FrequencyTrie.Builder<V> copyOf(final FrequencyTrie<V> source,
118
            final IntFunction<V[]> arrayFactory, final ReductionMode reductionMode) {
119
        Objects.requireNonNull(reductionMode, "reductionMode");
120 1 1. copyOf : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::copyOf → KILLED
        return copyOf(source, arrayFactory, ReductionSettings.withDefaults(reductionMode));
121
    }
122
123
    /**
124
     * Reconstructs a compiled trie with every stored value transformed to another
125
     * value type.
126
     *
127
     * <p>
128
     * The method preserves logical keys, local value counts, trie metadata, and the
129
     * supplied reduction settings. It is intended for runtime specialization, such
130
     * as replacing serialized patch-command strings with precompiled patch command
131
     * objects without changing the persisted binary trie format.
132
     * </p>
133
     *
134
     * @param source            source compiled trie
135
     * @param arrayFactory      array factory for mapped values
136
     * @param reductionSettings reduction settings for the mapped trie
137
     * @param valueMapper       value mapping function
138
     * @param <S>               source value type
139
     * @param <T>               target value type
140
     * @return compiled trie containing mapped values
141
     * @throws NullPointerException if any argument is {@code null}
142
     */
143
    public static <S, T> FrequencyTrie<T> mapValues(final FrequencyTrie<S> source,
144
            final IntFunction<T[]> arrayFactory, final ReductionSettings reductionSettings,
145
            final Function<? super S, ? extends T> valueMapper) {
146
        Objects.requireNonNull(source, "source");
147
        Objects.requireNonNull(arrayFactory, "arrayFactory");
148
        Objects.requireNonNull(reductionSettings, "reductionSettings");
149
        Objects.requireNonNull(valueMapper, "valueMapper");
150
151
        final Map<CompiledNode<S>, CompiledNode<T>> cache = new IdentityHashMap<>();
152
        final CompiledNode<T> mappedRoot = mapCompiledNode(source.root(), arrayFactory, valueMapper, cache);
153
        final TrieMetadata metadata = TrieMetadata.forCompilation(source.traversalDirection(), reductionSettings,
154
                source.metadata().diacriticProcessingMode(), source.metadata().caseProcessingMode());
155
156
        LOGGER.log(Level.FINE, "Mapped compiled trie values to a specialized value type.");
157 1 1. mapValues : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapValues → KILLED
        return FrequencyTrie.fromCompiled(arrayFactory, mappedRoot, metadata);
158
    }
159
160
    /**
161
     * Reconstructs a compiled trie with every stored value transformed to another
162
     * value type using default settings for the supplied reduction mode.
163
     *
164
     * @param source        source compiled trie
165
     * @param arrayFactory  array factory for mapped values
166
     * @param reductionMode reduction mode for the mapped trie
167
     * @param valueMapper   value mapping function
168
     * @param <S>           source value type
169
     * @param <T>           target value type
170
     * @return compiled trie containing mapped values
171
     * @throws NullPointerException if any argument is {@code null}
172
     */
173
    public static <S, T> FrequencyTrie<T> mapValues(final FrequencyTrie<S> source,
174
            final IntFunction<T[]> arrayFactory, final ReductionMode reductionMode,
175
            final Function<? super S, ? extends T> valueMapper) {
176
        Objects.requireNonNull(reductionMode, "reductionMode");
177 1 1. mapValues : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapValues → NO_COVERAGE
        return mapValues(source, arrayFactory, ReductionSettings.withDefaults(reductionMode), valueMapper);
178
    }
179
180
    /**
181
     * Computes structural statistics for one compiled trie.
182
     *
183
     * <p>
184
     * Each unique node instance contributes once to storage counts. Root-to-leaf
185
     * path statistics are computed independently with memoized dynamic programming,
186
     * so every logical path through shared reduced subtrees contributes at its
187
     * actual depth.
188
     * </p>
189
     *
190
     * @param trie source compiled trie
191
     * @return structural statistics
192
     * @throws NullPointerException if {@code trie} is {@code null}
193
     */
194
    public static TrieStatistics computeStatistics(final FrequencyTrie<?> trie) {
195
        Objects.requireNonNull(trie, "trie");
196
        final Map<CompiledNode<?>, Boolean> visited = new IdentityHashMap<>();
197
        final Set<Object> distinctValues = new HashSet<>();
198
        final StructuralCounters counters = new StructuralCounters();
199 1 1. computeStatistics : removed call to org/egothor/stemmer/FrequencyTrieBuilders::collectStructuralStats → KILLED
        collectStructuralStats(trie.root(), visited, distinctValues, counters);
200
201
        final Map<CompiledNode<?>, PathSummary> pathCache = new IdentityHashMap<>();
202
        final PathSummary paths = summarizePaths(trie.root(), pathCache);
203 1 1. computeStatistics : negated conditional → KILLED
        final double averageLeafDepth = paths.leafPathCount() == 0L ? 0.0d
204 1 1. computeStatistics : Replaced double division with multiplication → KILLED
                : paths.totalLeafDepth() / (double) paths.leafPathCount();
205 1 1. computeStatistics : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::computeStatistics → KILLED
        return new TrieStatistics(counters.internalNodes, counters.leafNodes, counters.edges,
206
                counters.acceptingLeaves, counters.valueReferences, distinctValues.size(),
207
                paths.leafPathCount(), paths.longestPath(), averageLeafDepth,
208
                counters.denseLookupNodes, counters.denseTableSlots);
209
    }
210
211
    /**
212
     * Recursive depth-first helper that accumulates trie structure counters.
213
     *
214
     * @param node           current node
215
     * @param visited        identity set of already-visited nodes
216
     * @param distinctValues distinct stored values
217
     * @param counters       mutable structural counters
218
     */
219
    private static void collectStructuralStats(final CompiledNode<?> node,
220
            final Map<CompiledNode<?>, Boolean> visited, final Set<Object> distinctValues,
221
            final StructuralCounters counters) {
222 1 1. collectStructuralStats : negated conditional → KILLED
        if (visited.put(node, Boolean.TRUE) != null) {
223
            return;
224
        }
225
        counters.edges = checkedAdd(counters.edges, node.edgeCount(), "edge count");
226
        counters.valueReferences = checkedAdd(counters.valueReferences, node.valueCount(), "value-reference count");
227
        for (final Object value : node.orderedValues()) {
228
            distinctValues.add(value);
229
        }
230 1 1. collectStructuralStats : negated conditional → KILLED
        if (node.isLeaf()) {
231
            counters.leafNodes = checkedAdd(counters.leafNodes, 1L, "leaf-node count");
232 1 1. collectStructuralStats : negated conditional → SURVIVED
            if (node.acceptsRemainingInput()) {
233
                counters.acceptingLeaves = checkedAdd(counters.acceptingLeaves, 1L, "accepting-leaf count");
234
            }
235
        } else {
236
            counters.internalNodes = checkedAdd(counters.internalNodes, 1L, "internal-node count");
237
        }
238 1 1. collectStructuralStats : negated conditional → SURVIVED
        if (node.hasDenseLookup()) {
239
            counters.denseLookupNodes = checkedAdd(counters.denseLookupNodes, 1L, "dense-lookup-node count");
240
            counters.denseTableSlots = checkedAdd(counters.denseTableSlots, node.denseTableLength(),
241
                    "dense-table-slot count");
242
        }
243
        for (final CompiledNode<?> child : node.children()) {
244 1 1. collectStructuralStats : removed call to org/egothor/stemmer/FrequencyTrieBuilders::collectStructuralStats → KILLED
            collectStructuralStats(child, visited, distinctValues, counters);
245
        }
246
    }
247
248
    /**
249
     * Computes all logical root-to-leaf suffix paths below one node.
250
     *
251
     * @param node  current node
252
     * @param cache identity-keyed summaries for shared subtrees
253
     * @return immutable path summary relative to {@code node}
254
     */
255
    private static PathSummary summarizePaths(final CompiledNode<?> node,
256
            final Map<CompiledNode<?>, PathSummary> cache) {
257
        final PathSummary existing = cache.get(node);
258 1 1. summarizePaths : negated conditional → KILLED
        if (existing != null) {
259 1 1. summarizePaths : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::summarizePaths → KILLED
            return existing;
260
        }
261
        final PathSummary result;
262 1 1. summarizePaths : negated conditional → KILLED
        if (node.isLeaf()) {
263
            result = new PathSummary(1L, 0L, 0L);
264
        } else {
265
            long leafPaths = 0L;
266
            long totalDepth = 0L;
267
            long longestPath = 0L;
268
            for (final CompiledNode<?> child : node.children()) {
269
                final PathSummary childSummary = summarizePaths(child, cache);
270
                leafPaths = checkedAdd(leafPaths, childSummary.leafPathCount(), "logical leaf-path count");
271
                totalDepth = checkedAdd(totalDepth,
272
                        checkedAdd(childSummary.totalLeafDepth(), childSummary.leafPathCount(),
273
                                "logical leaf-depth sum"),
274
                        "logical leaf-depth sum");
275
                longestPath = Math.max(longestPath,
276
                        checkedAdd(childSummary.longestPath(), 1L, "longest logical path"));
277
            }
278
            result = new PathSummary(leafPaths, totalDepth, longestPath);
279
        }
280
        cache.put(node, result);
281 1 1. summarizePaths : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::summarizePaths → KILLED
        return result;
282
    }
283
284
    /** Adds one structural quantity with an explicit overflow failure. */
285
    private static long checkedAdd(final long left, final long right, final String label) {
286
        try {
287 1 1. checkedAdd : replaced long return with 0 for org/egothor/stemmer/FrequencyTrieBuilders::checkedAdd → KILLED
            return Math.addExact(left, right);
288
        } catch (final ArithmeticException exception) {
289
            throw new IllegalStateException("Arithmetic overflow while calculating trie " + label + '.', exception);
290
        }
291
    }
292
293
    /** Mutable counters confined to one statistics traversal. */
294
    private static final class StructuralCounters {
295
        private long internalNodes;
296
        private long leafNodes;
297
        private long edges;
298
        private long acceptingLeaves;
299
        private long valueReferences;
300
        private long denseLookupNodes;
301
        private long denseTableSlots;
302
    }
303
304
    /** Memoized logical-path summary relative to one compiled node. */
305
    private record PathSummary(long leafPathCount, long totalLeafDepth, long longestPath) { }
306
307
    /**
308
     * Copies one compiled node and all reachable descendants into the target
309
     * builder.
310
     *
311
     * @param node               current compiled node
312
     * @param keyBuilder         current key builder
313
     * @param builder            target mutable builder
314
     * @param traversalDirection logical key traversal direction used by the source
315
     * @param <V>                value type
316
     */
317
    private static <V> void copyNode(final CompiledNode<V> node, final StringBuilder keyBuilder,
318
            final FrequencyTrie.Builder<V> builder, final WordTraversalDirection traversalDirection) {
319
        final String logicalKey = traversalDirection.traversalPathToLogicalKey(keyBuilder);
320 2 1. copyNode : changed conditional boundary → KILLED
2. copyNode : negated conditional → KILLED
        for (int valueIndex = 0; valueIndex < node.orderedValues().length; valueIndex++) {
321
            builder.put(logicalKey, node.orderedValues()[valueIndex], node.orderedCounts()[valueIndex]);
322
        }
323
324 2 1. copyNode : changed conditional boundary → KILLED
2. copyNode : negated conditional → KILLED
        for (int childIndex = 0; childIndex < node.edgeLabels().length; childIndex++) {
325
            keyBuilder.append(node.edgeLabels()[childIndex]);
326 1 1. copyNode : removed call to org/egothor/stemmer/FrequencyTrieBuilders::copyNode → KILLED
            copyNode(node.children()[childIndex], keyBuilder, builder, traversalDirection);
327 2 1. copyNode : removed call to java/lang/StringBuilder::setLength → KILLED
2. copyNode : Replaced integer subtraction with addition → KILLED
            keyBuilder.setLength(keyBuilder.length() - 1);
328
        }
329
    }
330
331
    /**
332
     * Maps one compiled node graph while preserving canonical sharing and accepting
333
     * leaf semantics.
334
     *
335
     * @param node         source node
336
     * @param arrayFactory target value array factory
337
     * @param valueMapper  value mapper
338
     * @param cache        identity cache for shared compiled nodes
339
     * @param <S>          source value type
340
     * @param <T>          target value type
341
     * @return mapped compiled node
342
     */
343
    private static <S, T> CompiledNode<T> mapCompiledNode(final CompiledNode<S> node,
344
            final IntFunction<T[]> arrayFactory, final Function<? super S, ? extends T> valueMapper,
345
            final Map<CompiledNode<S>, CompiledNode<T>> cache) {
346
        final CompiledNode<T> existing = cache.get(node);
347 1 1. mapCompiledNode : negated conditional → KILLED
        if (existing != null) {
348 1 1. mapCompiledNode : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapCompiledNode → KILLED
            return existing;
349
        }
350
351
        final CompiledNode<S>[] sourceChildren = node.children();
352
        @SuppressWarnings("unchecked")
353
        final CompiledNode<T>[] mappedChildren = new CompiledNode[sourceChildren.length];
354 2 1. mapCompiledNode : changed conditional boundary → KILLED
2. mapCompiledNode : negated conditional → KILLED
        for (int childIndex = 0; childIndex < sourceChildren.length; childIndex++) {
355
            mappedChildren[childIndex] = mapCompiledNode(sourceChildren[childIndex], arrayFactory, valueMapper, cache);
356
        }
357
358
        final S[] sourceValues = node.orderedValues();
359
        final T[] mappedValues = arrayFactory.apply(sourceValues.length);
360 2 1. mapCompiledNode : negated conditional → KILLED
2. mapCompiledNode : changed conditional boundary → KILLED
        for (int valueIndex = 0; valueIndex < sourceValues.length; valueIndex++) {
361
            mappedValues[valueIndex] = valueMapper.apply(sourceValues[valueIndex]);
362
        }
363
364
        final CompiledNode<T> mapped = new CompiledNode<>(node.edgeLabels().clone(), mappedChildren, mappedValues,
365
                node.acceptsRemainingInput(), CompiledNode.DEFAULT_MAX_EXPANDED_INDEX, node.orderedCounts().clone());
366
        cache.put(node, mapped);
367 1 1. mapCompiledNode : replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapCompiledNode → KILLED
        return mapped;
368
    }
369
}

Mutations

100

1.1
Location : copyOf
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldPreserveLocalCountsAndOrdering()]
removed call to org/egothor/stemmer/FrequencyTrieBuilders::copyNode → KILLED

103

1.1
Location : copyOf
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldReconstructEmptyTrie()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::copyOf → KILLED

120

1.1
Location : copyOf
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldReconstructUsingReductionModeShortcut()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::copyOf → KILLED

157

1.1
Location : mapValues
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapValues → KILLED

177

1.1
Location : mapValues
Killed by : none
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapValues → NO_COVERAGE

199

1.1
Location : computeStatistics
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
removed call to org/egothor/stemmer/FrequencyTrieBuilders::collectStructuralStats → KILLED

203

1.1
Location : computeStatistics
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
negated conditional → KILLED

204

1.1
Location : computeStatistics
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
Replaced double division with multiplication → KILLED

205

1.1
Location : computeStatistics
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::computeStatistics → KILLED

222

1.1
Location : collectStructuralStats
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
negated conditional → KILLED

230

1.1
Location : collectStructuralStats
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
negated conditional → KILLED

232

1.1
Location : collectStructuralStats
Killed by : none
negated conditional → SURVIVED
Covering tests

238

1.1
Location : collectStructuralStats
Killed by : none
negated conditional → SURVIVED
Covering tests

244

1.1
Location : collectStructuralStats
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
removed call to org/egothor/stemmer/FrequencyTrieBuilders::collectStructuralStats → KILLED

258

1.1
Location : summarizePaths
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
negated conditional → KILLED

259

1.1
Location : summarizePaths
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::summarizePaths → KILLED

262

1.1
Location : summarizePaths
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
negated conditional → KILLED

281

1.1
Location : summarizePaths
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::summarizePaths → KILLED

287

1.1
Location : checkedAdd
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMeasureLogicalPathsThroughSharedSubtree()]
replaced long return with 0 for org/egothor/stemmer/FrequencyTrieBuilders::checkedAdd → KILLED

320

1.1
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldReconstructEmptyTrie()]
changed conditional boundary → KILLED

2.2
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldReconstructEmptyTrie()]
negated conditional → KILLED

324

1.1
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldReconstructEmptyTrie()]
changed conditional boundary → KILLED

2.2
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldReconstructEmptyTrie()]
negated conditional → KILLED

326

1.1
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldPreserveLocalCountsAndOrdering()]
removed call to org/egothor/stemmer/FrequencyTrieBuilders::copyNode → KILLED

327

1.1
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldPreserveCompiledSemanticsAfterReconstruction()]
removed call to java/lang/StringBuilder::setLength → KILLED

2.2
Location : copyNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldPreserveCompiledSemanticsAfterReconstruction()]
Replaced integer subtraction with addition → KILLED

347

1.1
Location : mapCompiledNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
negated conditional → KILLED

348

1.1
Location : mapCompiledNode
Killed by : org.egothor.stemmer.benchmark.generalization.EditCostSensitivityApplicationTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.generalization.EditCostSensitivityApplicationTest]/[method:stemShouldReturnCorrectStemForTrainingWords()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapCompiledNode → KILLED

354

1.1
Location : mapCompiledNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
changed conditional boundary → KILLED

2.2
Location : mapCompiledNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
negated conditional → KILLED

360

1.1
Location : mapCompiledNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
negated conditional → KILLED

2.2
Location : mapCompiledNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
changed conditional boundary → KILLED

367

1.1
Location : mapCompiledNode
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldMapValuesWhilePreservingKeysAndCounts()]
replaced return value with null for org/egothor/stemmer/FrequencyTrieBuilders::mapCompiledNode → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1