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

eXist-db / exist / 40657517912

28 Oct 2026 08:32AM UTC coverage: 58.121% (-0.08%) from 58.196%
40657517912

push

github

web-flow
Merge pull request #6938 from eXist-db/dependabot/github_actions/actions-0c219a018e

Bump docker/login-action from 4.6.0 to 4.7.0 in the actions group

32462 of 61752 branches covered (52.57%)

Branch coverage included in aggregate %.

85521 of 141244 relevant lines covered (60.55%)

2.72 hits per line

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

10.0
/exist-core/src/main/java/org/exist/storage/statistics/NodeStats.java
1
/*
2
 * eXist-db Open Source Native XML Database
3
 * Copyright (C) 2001 The eXist-db Authors
4
 *
5
 * info@exist-db.org
6
 * http://www.exist-db.org
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 */
22
package org.exist.storage.statistics;
23

24
import org.exist.Namespaces;
25
import org.exist.dom.QName;
26
import org.exist.dom.persistent.SymbolTable;
27
import org.exist.storage.NodePath;
28
import org.w3c.dom.Node;
29
import org.xml.sax.ContentHandler;
30
import org.xml.sax.SAXException;
31
import org.xml.sax.helpers.AttributesImpl;
32

33
import java.nio.ByteBuffer;
34
import java.util.List;
35

36
/**
37
 * Collects statistics for a single node in the data guide.
38
 */
39
class NodeStats {
40

41
    private QName qname;
42
    private int nodeCount = 0;
3 ✔
43
    private int maxDepth = 0;
3 ✔
44

45
    transient private int depth = 0;
3 ✔
46

47
    protected NodeStats parent = null;
3 ✔
48
    protected NodeStats[] children = null;
3 ✔
49

50
    protected NodeStats(QName qname) {
51
        this(null, qname);
4 ✔
52
    }
1 ✔
53

54
    protected NodeStats(NodeStats parent, QName qname) {
2 ✔
55
        this.parent = parent;
3 ✔
56
        this.qname = qname;
3 ✔
57
    }
1 ✔
58

59
    public void incDepth() {
60
        this.depth++;
×
61
    }
×
62

63
    public void updateMaxDepth() {
64
        if (depth > maxDepth)
×
65
            {maxDepth = depth;}
×
66
        depth = 0;
×
67
    }
×
68

69
    public int getMaxDepth() {
70
        return maxDepth;
×
71
    }
72
    
73
    protected void addOccurrence() {
74
        nodeCount++;
×
75
    }
×
76

77
    protected NodeStats addChild(QName qn) {
78
        if (children != null) {
×
79
            for (final NodeStats child : children) {
×
80
                if (child.qname.equals(qn)) {
×
81
                    return child;
×
82
                }
83
            }
84
        }
85
        if (children == null) {
×
86
            children = new NodeStats[1];
×
87
        } else {
×
88
            NodeStats[] tc = new NodeStats[children.length + 1];
×
89
            System.arraycopy(children, 0, tc, 0, children.length);
×
90
            children = tc;
×
91
        }
92
        children[children.length - 1] = new NodeStats(this, qn);
×
93
        return children[children.length - 1];
×
94
    }
95

96
    protected void mergeInto(DataGuide other, NodePath currentPath) {
97
        NodePath newPath;
98
        if (qname == null)
×
99
            {newPath = currentPath;}
×
100
        else {
101
            newPath = new NodePath(currentPath);
×
102
            newPath.addComponent(qname);
×
103
            other.add(newPath, this);
×
104
        }
105

106
        if (children != null) {
×
107
            for (final NodeStats child : children) {
×
108
                child.mergeInto(other, newPath);
×
109
            }
110
        }
111
    }
×
112

113
    protected void mergeStats(NodeStats other) {
114
        nodeCount += other.nodeCount;
×
115
        if (other.maxDepth > maxDepth)
×
116
            {maxDepth = other.maxDepth;}
×
117
    }
×
118

119
    protected int getSize() {
120
        int s = qname == null ? 0 : 1;
6 !
121
        if (children != null) {
3 !
122
            for (NodeStats child : children) {
×
123
                s += child.getSize();
×
124
            }
125
        }
126
        return s;
2 ✔
127
    }
128

129
    protected void getMaxParentDepth(QName name, NodeStats max) {
130
        if (parent != null && qname != null && qname.equals(name)) {
×
131
            max.maxDepth = Math.max(parent.maxDepth, max.maxDepth);
×
132
        }
133
        if (children != null) {
×
134
            for (NodeStats child : children) {
×
135
                child.getMaxParentDepth(name, max);
×
136
            }
137
        }
138
    }
×
139

140
    protected void write(ByteBuffer buffer, SymbolTable symbols) {
141
        buffer.putShort(symbols.getNSSymbol(qname.getNamespaceURI()));
×
142
        buffer.putShort(symbols.getSymbol(qname.getLocalPart()));
×
143
        buffer.putInt(nodeCount);
×
144
        buffer.putInt(maxDepth);
×
145

146
        buffer.putInt(children == null ? 0: children.length);
×
147
        if (children != null) {
×
148
            for (NodeStats child : children) {
×
149
                child.write(buffer, symbols);
×
150
            }
151
        }
152
    }
×
153

154
    protected void read(ByteBuffer buffer, SymbolTable symbols) {
155
        final short nsid = buffer.getShort();
×
156
        final short localid = buffer.getShort();
×
157
        final String namespaceURI = symbols.getNamespace(nsid);
×
158
        final String localName = symbols.getName(localid);
×
159
        qname = symbols.getQName(Node.ELEMENT_NODE, namespaceURI,
×
160
            localName, "");
×
161
        nodeCount = buffer.getInt();
×
162
        maxDepth = buffer.getInt();
×
163

164
        final int childCount = buffer.getInt();
×
165
        if (childCount > 0) {
×
166
            children = new NodeStats[childCount];
×
167
            for (int i = 0; i < childCount; i++) {
×
168
                children[i] = new NodeStats(this, null);
×
169
                children[i].read(buffer, symbols);
×
170
            }
171
        }
172
    }
×
173

174
    protected void dump(StringBuilder currentPath, List<StringBuilder> paths) {
175
        StringBuilder newPath;
176
        if (qname == null)
×
177
            {newPath = currentPath;}
×
178
        else {
179
            newPath = new StringBuilder(currentPath);
×
180
            if (!newPath.isEmpty())
×
181
                {newPath.append(" -> ");}
×
182
            newPath.append(qname);
×
183
            newPath.append('[').append(nodeCount).append(',');
×
184
            newPath.append(maxDepth).append(']');
×
185
        }
186
        paths.add(newPath);
×
187
        if (children != null) {
×
188
            for (final NodeStats child : children) {
×
189
                child.dump(newPath, paths);
×
190
            }
191
        }
192
    }
×
193

194
    public void toSAX(ContentHandler handler) throws SAXException {
195
        final AttributesImpl attribs = new AttributesImpl();
×
196
        attribs.addAttribute("", "name", "name", "CDATA", qname.getLocalPart());
×
197
        attribs.addAttribute("", "namespace", "namespace", "CDATA", qname.getNamespaceURI());
×
198
        attribs.addAttribute("", "node-count", "node-count", "CDATA", Integer.toString(nodeCount));
×
199
        attribs.addAttribute("", "max-depth", "max-depth", "CDATA", Integer.toString(maxDepth));
×
200
        handler.startElement(Namespaces.EXIST_NS, "node", "node", attribs);
×
201
        if (children != null) {
×
202
            for (NodeStats child : children) {
×
203
                child.toSAX(handler);
×
204
            }
205
        }
206
        handler.endElement(Namespaces.EXIST_NS, "node", "node");
×
207
    }
×
208
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc