MutableNode.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.trie;
32
33
import java.util.LinkedHashMap;
34
import java.util.Map;
35
36
/**
37
 * Mutable build-time node.
38
 *
39
 * <p>
40
 * The maps exposed by the accessors are the internal mutable backing state of
41
 * the node. They are returned directly for efficiency and are intended only for
42
 * closely related trie-building infrastructure.
43
 * </p>
44
 *
45
 * <p>
46
 * Instances are mutable and not thread-safe. The owning builder is responsible
47
 * for confinement and for ensuring that the exposed maps are not retained after
48
 * compilation.
49
 * </p>
50
 *
51
 * @param <V> value type
52
 */
53
public final class MutableNode<V> {
54
55
    /**
56
     * Child nodes indexed by transition character.
57
     */
58
    private final Map<Character, MutableNode<V>> children;
59
60
    /**
61
     * Local terminal value counts stored exactly at this node.
62
     */
63
    private final Map<V, Integer> valueCounts;
64
65
    /**
66
     * Whether this node was a contracted accepting leaf in a source compiled
67
     * trie. Set only when a builder is reconstructed from a compiled trie (see
68
     * {@code FrequencyTrieBuilders.copyOf}); it is preserved through reduction so
69
     * the "accepts remaining input" generalization survives a round-trip even
70
     * when the original member paths were contracted away and cannot be replayed.
71
     */
72
    private boolean acceptsRemainingInput;
73
74
    /**
75
     * Creates an empty node.
76
     */
77
    public MutableNode() {
78
        this.children = new LinkedHashMap<>();
79
        this.valueCounts = new LinkedHashMap<>();
80
    }
81
82
    /**
83
     * Returns whether this node is marked as accepting remaining input.
84
     *
85
     * @return {@code true} when this node accepts any remaining lookup input
86
     */
87
    public boolean acceptsRemainingInput() {
88 2 1. acceptsRemainingInput : replaced boolean return with true for org/egothor/stemmer/trie/MutableNode::acceptsRemainingInput → KILLED
2. acceptsRemainingInput : replaced boolean return with false for org/egothor/stemmer/trie/MutableNode::acceptsRemainingInput → KILLED
        return this.acceptsRemainingInput;
89
    }
90
91
    /**
92
     * Marks this node as accepting remaining input.
93
     */
94
    public void markAcceptsRemainingInput() {
95
        this.acceptsRemainingInput = true;
96
    }
97
98
    /**
99
     * Clears the accepting-remaining-input marker.
100
     *
101
     * <p>
102
     * This transition is required when the last local value is removed: an
103
     * accepting node without a value cannot resolve a lookup and is rejected by
104
     * the compiled-node invariant.
105
     * </p>
106
     */
107
    public void clearAcceptsRemainingInput() {
108
        this.acceptsRemainingInput = false;
109
    }
110
111
    /**
112
     * Returns the internal child-node map indexed by transition character.
113
     *
114
     * <p>
115
     * The returned map is the internal mutable backing state of this node and is
116
     * exposed only for efficient cooperation with trie-building infrastructure.
117
     *
118
     * @return internal child-node map
119
     */
120
    public Map<Character, MutableNode<V>> children() {
121 1 1. children : replaced return value with Collections.emptyMap for org/egothor/stemmer/trie/MutableNode::children → KILLED
        return this.children;
122
    }
123
124
    /**
125
     * Returns the internal local terminal value-count map.
126
     *
127
     * <p>
128
     * The returned map is the internal mutable backing state of this node and is
129
     * exposed only for efficient cooperation with trie-building infrastructure.
130
     *
131
     * @return internal local value-count map
132
     */
133
    public Map<V, Integer> valueCounts() {
134 1 1. valueCounts : replaced return value with Collections.emptyMap for org/egothor/stemmer/trie/MutableNode::valueCounts → KILLED
        return this.valueCounts;
135
    }
136
137
}

Mutations

88

1.1
Location : acceptsRemainingInput
Killed by : org.egothor.stemmer.FrequencyTrieTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieTest]/[method:trieRejectsNullLookupKeys()]
replaced boolean return with true for org/egothor/stemmer/trie/MutableNode::acceptsRemainingInput → KILLED

2.2
Location : acceptsRemainingInput
Killed by : org.egothor.stemmer.FrequencyTrieBuildersTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.FrequencyTrieBuildersTest]/[method:shouldRemoveContractedAcceptingGeneralization()]
replaced boolean return with false for org/egothor/stemmer/trie/MutableNode::acceptsRemainingInput → KILLED

121

1.1
Location : children
Killed by : org.egothor.stemmer.trie.MutableNodeTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.trie.MutableNodeTest]/[method:shouldExposeMutableBackingChildrenMap()]
replaced return value with Collections.emptyMap for org/egothor/stemmer/trie/MutableNode::children → KILLED

134

1.1
Location : valueCounts
Killed by : org.egothor.stemmer.trie.MutableNodeTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.trie.MutableNodeTest]/[method:shouldExposeMutableBackingValueCountsMap()]
replaced return value with Collections.emptyMap for org/egothor/stemmer/trie/MutableNode::valueCounts → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1