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

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

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

0.0
/exist-core/src/main/java/org/exist/storage/lock/LockTableUtils.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 */
24
package org.exist.storage.lock;
25

26
import java.io.Writer;
27
import java.util.GregorianCalendar;
28
import java.util.List;
29
import java.util.Map;
30
import org.exist.storage.lock.Lock.LockMode;
31
import org.exist.storage.lock.Lock.LockType;
32
import org.exist.storage.lock.LockTable.LockCountTraces;
33
import org.exist.storage.lock.LockTable.LockModeOwner;
34
import org.exist.xquery.value.TimeUtils;
35

36
import javax.xml.datatype.XMLGregorianCalendar;
37
import javax.xml.stream.XMLOutputFactory;
38
import javax.xml.stream.XMLStreamException;
39
import javax.xml.stream.XMLStreamWriter;
40

41
/**
42
 * Utilities for working with the Lock Table
43
 *
44
 * @author <a href="mailto:adam@evolvedbinary.com">Adam Retter</a>
45
 */
46
public class LockTableUtils {
×
47

48
    private static final String EOL = System.getProperty("line.separator");
×
49

50
    public static String stateToString(final LockTable lockTable, final boolean includeStack) {
51
        final Map<String, Map<LockType, List<LockModeOwner>>> attempting = lockTable.getAttempting();
×
52
        final Map<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquired = lockTable.getAcquired();
×
53

54
        final StringBuilder builder = new StringBuilder();
×
55

56
        builder
×
57
                .append(EOL)
×
58
                .append("Acquired Locks").append(EOL)
×
59
                .append("------------------------------------").append(EOL);
×
60

61
        for(final Map.Entry<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquire : acquired.entrySet()) {
×
62
            builder.append(acquire.getKey()).append(EOL);
×
63
            for(final Map.Entry<LockType, Map<LockMode, Map<String, LockCountTraces>>> type : acquire.getValue().entrySet()) {
×
64
                builder.append('\t').append(type.getKey()).append(EOL);
×
65
                for(final Map.Entry<LockMode, Map<String, LockCountTraces>> lockModeOwners : type.getValue().entrySet()) {
×
66
                    builder
×
67
                            .append("\t\t").append(lockModeOwners.getKey())
×
68
                            .append('\t');
×
69

70
                    boolean firstOwner = true;
×
71
                    for(final Map.Entry<String, LockCountTraces> ownerHoldCount : lockModeOwners.getValue().entrySet()) {
×
72
                        if(!firstOwner) {
×
73
                            builder.append(", ");
×
74
                        } else {
×
75
                            firstOwner = false;
×
76
                        }
77
                        final LockCountTraces holdCount = ownerHoldCount.getValue();
×
78
                        builder.append(ownerHoldCount.getKey())
×
79
                                .append(" (count=").append(holdCount.count).append(")");
×
80
                        if (holdCount.traces != null && includeStack) {
×
81
                            for (int i = 0; i < holdCount.traces.size(); i++) {
×
82
                                 final StackTraceElement[] trace = holdCount.traces.get(i);
×
83
                                 builder
×
84
                                         .append(EOL)
×
85
                                         .append("\t\t\tTrace ").append(i).append(": ").append(EOL);
×
86
                                for (StackTraceElement stackTraceElement : trace) {
×
87
                                    builder.append("\t\t\t\t").append(stackTraceElement).append(EOL);
×
88
                                }
89
                            }
90
                        }
91
                    }
92
                    builder.append(EOL);
×
93
                }
94
            }
95
        }
96

97
        builder.append(EOL).append(EOL);
×
98

99
        builder
×
100
                .append("Attempting Locks").append(EOL)
×
101
                .append("------------------------------------").append(EOL);
×
102

103
        for(final Map.Entry<String, Map<Lock.LockType, List<LockTable.LockModeOwner>>> attempt : attempting.entrySet()) {
×
104
            builder.append(attempt.getKey()).append(EOL);
×
105
            for(final Map.Entry<Lock.LockType, List<LockTable.LockModeOwner>> type : attempt.getValue().entrySet()) {
×
106
                builder.append('\t').append(type.getKey()).append(EOL);
×
107
                for(final LockTable.LockModeOwner lockModeOwner : type.getValue()) {
×
108
                    builder
×
109
                            .append("\t\t").append(lockModeOwner.getLockMode())
×
110
                            .append('\t').append(lockModeOwner.getOwnerThread());
×
111
                            if (lockModeOwner.trace != null && includeStack) {
×
112
                                builder.append(EOL).append("\t\t\tTrace ").append(": ").append(EOL);
×
113
                                for (int i = 0; i < lockModeOwner.trace.length; i++) {
×
114
                                    builder.append("\t\t\t\t").append(lockModeOwner.trace[i]).append(EOL);
×
115
                                }
116
                            }
117
                            builder.append(EOL);
×
118
                }
119
            }
120
        }
121

122
        return builder.toString();
×
123
    }
124

125
    public static void stateToXml(final LockTable lockTable, final boolean includeStack, final Writer writer) throws XMLStreamException {
126
        final GregorianCalendar cal = new GregorianCalendar();
×
127

128
        final Map<String, Map<LockType, List<LockModeOwner>>> attempting = lockTable.getAttempting();
×
129
        final Map<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquired = lockTable.getAcquired();
×
130

131
        final XMLOutputFactory outputFactory = XMLOutputFactory.newFactory();
×
132
        final XMLStreamWriter xmlWriter = outputFactory.createXMLStreamWriter(writer);
×
133

134
        xmlWriter.writeStartDocument();
×
135
        xmlWriter.writeStartElement("lock-table");
×
136
        final XMLGregorianCalendar xmlCal = TimeUtils.getInstance().newXMLGregorianCalendar(cal);
×
137
        xmlWriter.writeAttribute("timestamp", xmlCal.toXMLFormat());
×
138

139
        // acquired locks
140
        xmlWriter.writeStartElement("acquired");
×
141
        for(final Map.Entry<String, Map<LockType, Map<LockMode, Map<String, LockCountTraces>>>> acquire : acquired.entrySet()) {
×
142
            xmlWriter.writeStartElement("lock");
×
143
            xmlWriter.writeAttribute("id", acquire.getKey());
×
144

145
            for(final Map.Entry<LockType, Map<LockMode, Map<String, LockCountTraces>>> type : acquire.getValue().entrySet()) {
×
146
                xmlWriter.writeStartElement("type");
×
147
                xmlWriter.writeAttribute("id", type.getKey().name());
×
148

149
                for(final Map.Entry<LockMode, Map<String, LockCountTraces>> lockModeOwners : type.getValue().entrySet()) {
×
150
                    xmlWriter.writeStartElement("mode");
×
151
                    xmlWriter.writeAttribute("id", lockModeOwners.getKey().name());
×
152

153
                    for(final Map.Entry<String, LockCountTraces> ownerHoldCount : lockModeOwners.getValue().entrySet()) {
×
154
                        xmlWriter.writeStartElement("thread");
×
155
                        xmlWriter.writeAttribute("id", ownerHoldCount.getKey());
×
156
                        final LockCountTraces holdCount = ownerHoldCount.getValue();
×
157
                        xmlWriter.writeAttribute("hold-count", Integer.toString(holdCount.count));
×
158

159
                        if (holdCount.traces != null && includeStack) {
×
160
                            for (int i = 0; i < holdCount.traces.size(); i++) {
×
161
                                xmlWriter.writeStartElement("stack-trace");
×
162
                                xmlWriter.writeAttribute("index", Integer.toString(i));
×
163

164
                                final StackTraceElement[] trace = holdCount.traces.get(i);
×
165
                                for (int j = 0; j < trace.length; j++) {
×
166
                                    xmlWriter.writeStartElement("call");
×
167
                                    final StackTraceElement call = trace[j];
×
168
                                    xmlWriter.writeAttribute("index", Integer.toString(j));
×
169
                                    xmlWriter.writeAttribute("class", call.getClassName());
×
170
                                    xmlWriter.writeAttribute("method", call.getMethodName());
×
171
                                    xmlWriter.writeAttribute("file", call.getFileName());
×
172
                                    xmlWriter.writeAttribute("line", Integer.toString(call.getLineNumber()));
×
173
                                    xmlWriter.writeCharacters(call.toString());
×
174
                                    xmlWriter.writeEndElement();
×
175
                                }
176

177
                                xmlWriter.writeEndElement();
×
178
                            }
179
                        }
180
                        xmlWriter.writeEndElement();
×
181
                    }
182
                    xmlWriter.writeEndElement();
×
183
                }
184
                xmlWriter.writeEndElement();
×
185
            }
186
            xmlWriter.writeEndElement();
×
187
        }
188
        xmlWriter.writeEndElement();
×
189

190

191
        // attempting locks
192
        xmlWriter.writeStartElement("attempting");
×
193
        for(final Map.Entry<String, Map<Lock.LockType, List<LockTable.LockModeOwner>>> attempt : attempting.entrySet()) {
×
194
            xmlWriter.writeStartElement("lock");
×
195
            xmlWriter.writeAttribute("id", attempt.getKey());
×
196

197
            for(final Map.Entry<Lock.LockType, List<LockTable.LockModeOwner>> type : attempt.getValue().entrySet()) {
×
198
                xmlWriter.writeStartElement("type");
×
199
                xmlWriter.writeAttribute("id", type.getKey().name());
×
200

201
                for(final LockTable.LockModeOwner lockModeOwner : type.getValue()) {
×
202
                    xmlWriter.writeStartElement("mode");
×
203
                    xmlWriter.writeAttribute("id", lockModeOwner.getLockMode().name());
×
204

205
                    xmlWriter.writeStartElement("thread");
×
206
                    xmlWriter.writeAttribute("id", lockModeOwner.getOwnerThread());
×
207

208
                    if (lockModeOwner.trace != null && includeStack) {
×
209
                        xmlWriter.writeStartElement("stack-trace");
×
210

211
                        for (int i = 0; i < lockModeOwner.trace.length; i++) {
×
212
                            xmlWriter.writeStartElement("call");
×
213
                            final StackTraceElement call = lockModeOwner.trace[i];
×
214
                            xmlWriter.writeAttribute("index", Integer.toString(i));
×
215
                            xmlWriter.writeAttribute("class", call.getClassName());
×
216
                            xmlWriter.writeAttribute("method", call.getMethodName());
×
217
                            xmlWriter.writeAttribute("file", call.getFileName());
×
218
                            xmlWriter.writeAttribute("line", Integer.toString(call.getLineNumber()));
×
219
                            xmlWriter.writeCharacters(call.toString());
×
220
                            xmlWriter.writeEndElement();
×
221
                        }
222

223
                        xmlWriter.writeEndElement();
×
224
                    }
225

226
                    xmlWriter.writeEndElement();
×
227

228
                    xmlWriter.writeEndElement();
×
229
                }
230

231
                xmlWriter.writeEndElement();
×
232
            }
233

234
            xmlWriter.writeEndElement();
×
235
        }
236

237
        xmlWriter.writeEndElement();
×
238

239
        xmlWriter.writeEndElement();
×
240
        xmlWriter.writeEndDocument();
×
241
    }
×
242
}
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