You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by fr...@apache.org on 2016/05/23 16:35:43 UTC
svn commit: r1745235 - in
/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak:
explorer/Explorer.java explorer/FileStoreWrapper.java
explorer/NodeStoreTree.java run/SegmentUtils.java
Author: frm
Date: Mon May 23 16:35:43 2016
New Revision: 1745235
URL: http://svn.apache.org/viewvc?rev=1745235&view=rev
Log:
OAK-4337 - Encapsulate every operation related to the FileStore in the same class
Added:
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/FileStoreWrapper.java (with props)
Modified:
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/Explorer.java
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/NodeStoreTree.java
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentUtils.java
Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/Explorer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/Explorer.java?rev=1745235&r1=1745234&r2=1745235&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/Explorer.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/Explorer.java Mon May 23 16:35:43 2016
@@ -18,11 +18,7 @@
*/
package org.apache.jackrabbit.oak.explorer;
-import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.readRevisions;
-
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
+import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
@@ -31,16 +27,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import javax.swing.JFrame;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JSeparator;
-import javax.swing.JSplitPane;
-import javax.swing.JTextArea;
-import javax.swing.UIManager;
+import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
import org.apache.commons.io.IOUtils;
@@ -53,21 +40,40 @@ import org.apache.commons.io.IOUtils;
*/
public class Explorer {
- private static String skip = "skip-size-check";
+ private static boolean getSkipSizeChecks(String... args) {
+ return args.length >= 2 && args[1].equalsIgnoreCase("skip-size-check");
+ }
+
+ private static void initLF() {
+ try {
+ for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
+ if ("Nimbus".equals(info.getName())) {
+ UIManager.setLookAndFeel(info.getClassName());
+ break;
+ }
+ }
+ } catch (Exception e) {
+ // If Nimbus is not available, you can set the GUI to another look
+ // and feel.
+ }
+ }
public static void main(String[] args) throws IOException {
new Explorer(args);
}
- public Explorer(String[] args) throws IOException {
+ private final FileStoreWrapper store;
+
+ private Explorer(String[] args) throws IOException {
if (args.length == 0) {
System.err.println("usage: explore <path> [skip-size-check]");
System.exit(1);
}
final File path = new File(args[0]);
- final boolean skipSizeCheck = args.length == 2
- && skip.equalsIgnoreCase(args[1]);
+ final boolean skipSizeCheck = getSkipSizeChecks(args);
+
+ this.store = new FileStoreWrapper(path);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
@@ -81,29 +87,13 @@ public class Explorer {
});
}
- private static void initLF() {
- try {
- for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
- if ("Nimbus".equals(info.getName())) {
- UIManager.setLookAndFeel(info.getClassName());
- break;
- }
- }
- } catch (Exception e) {
- // If Nimbus is not available, you can set the GUI to another look
- // and feel.
- }
- }
-
- private void createAndShowGUI(final File path, boolean skipSizeCheck)
- throws IOException {
-
+ private void createAndShowGUI(final File path, boolean skipSizeCheck) throws IOException {
JTextArea log = new JTextArea(5, 20);
log.setMargin(new Insets(5, 5, 5, 5));
log.setLineWrap(true);
log.setEditable(false);
- final NodeStoreTree treePanel = new NodeStoreTree(path, log, skipSizeCheck);
+ final NodeStoreTree treePanel = new NodeStoreTree(store, log, skipSizeCheck);
final JFrame frame = new JFrame("Explore " + path + " @head");
frame.addWindowListener(new java.awt.event.WindowAdapter() {
@@ -148,7 +138,7 @@ public class Explorer {
menuCompaction.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
- List<String> revs = readRevisions(path);
+ List<String> revs = store.readRevisions();
String s = (String) JOptionPane.showInputDialog(frame,
"Revert to a specified revision", "Time Machine",
JOptionPane.PLAIN_MESSAGE, null, revs.toArray(),
@@ -177,7 +167,6 @@ public class Explorer {
tarFiles.get(0));
if (s != null) {
treePanel.printTarInfo(s);
- return;
}
}
});
@@ -187,12 +176,11 @@ public class Explorer {
menuSCR.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
- String s = (String) JOptionPane.showInputDialog(frame,
+ String s = JOptionPane.showInputDialog(frame,
"Segment References\nUsage: <segmentId>",
"Segment References", JOptionPane.PLAIN_MESSAGE);
if (s != null) {
treePanel.printSegmentReferences(s);
- return;
}
}
});
@@ -202,12 +190,11 @@ public class Explorer {
menuDiff.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ev) {
- String s = (String) JOptionPane.showInputDialog(frame,
+ String s = JOptionPane.showInputDialog(frame,
"SegmentNodeState diff\nUsage: <recordId> <recordId> [<path>]",
"SegmentNodeState diff", JOptionPane.PLAIN_MESSAGE);
if (s != null) {
treePanel.printDiff(s);
- return;
}
}
});
Added: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/FileStoreWrapper.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/FileStoreWrapper.java?rev=1745235&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/FileStoreWrapper.java (added)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/FileStoreWrapper.java Mon May 23 16:35:43 2016
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.oak.explorer;
+
+import static com.google.common.collect.Sets.newHashSet;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.UUID;
+
+import com.google.common.collect.Maps;
+import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper;
+import org.apache.jackrabbit.oak.plugins.segment.PCMAnalyser;
+import org.apache.jackrabbit.oak.plugins.segment.RecordId;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentBlob;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStateHelper;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentPropertyState;
+import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+class FileStoreWrapper {
+
+ private final File path;
+
+ private FileStore.ReadOnlyStore store;
+
+ private Map<String, Set<UUID>> index;
+
+ FileStoreWrapper(File path) throws IOException {
+ this.path = path;
+ }
+
+ void open() throws IOException {
+ store = FileStore.builder(path).buildReadOnly();
+ index = store.getTarReaderIndex();
+ }
+
+ void close() {
+ store.close();
+ store = null;
+ index = null;
+ }
+
+ List<String> readRevisions() {
+ return FileStoreHelper.readRevisions(path);
+ }
+
+ Map<String, Set<UUID>> getTarReaderIndex() {
+ return store.getTarReaderIndex();
+ }
+
+ Map<UUID, List<UUID>> getTarGraph(String file) throws IOException {
+ return store.getTarGraph(file);
+ }
+
+ List<String> getTarFiles() {
+ return FileStoreHelper.getTarFiles(store);
+ }
+
+ void getGcRoots(UUID uuidIn, Map<UUID, Set<Entry<UUID, String>>> links) throws IOException {
+ FileStoreHelper.getGcRoots(store, uuidIn, links);
+ }
+
+ Set<UUID> getReferencedSegmentIds() {
+ Set<UUID> ids = newHashSet();
+
+ for (SegmentId id : store.getTracker().getReferencedSegmentIds()) {
+ ids.add(id.asUUID());
+ }
+
+ return ids;
+ }
+
+ NodeState getHead() {
+ return store.getHead();
+ }
+
+ NodeState readNodeState(String recordId) {
+ return new SegmentNodeState(RecordId.fromString(store.getTracker(), recordId));
+ }
+
+ void setRevision(String revision) {
+ store.setRevision(revision);
+ }
+
+ boolean isPersisted(NodeState state) {
+ return state instanceof SegmentNodeState;
+ }
+
+ boolean isPersisted(PropertyState state) {
+ return state instanceof SegmentPropertyState;
+ }
+
+ String getRecordId(NodeState state) {
+ if (state instanceof SegmentNodeState) {
+ return getRecordId((SegmentNodeState) state);
+ }
+
+ return null;
+ }
+
+ UUID getSegmentId(NodeState state) {
+ if (state instanceof SegmentNodeState) {
+ return getSegmentId((SegmentNodeState) state);
+ }
+
+ return null;
+ }
+
+ String getRecordId(PropertyState state) {
+ if (state instanceof SegmentPropertyState) {
+ return getRecordId((SegmentPropertyState) state);
+ }
+
+ return null;
+ }
+
+ UUID getSegmentId(PropertyState state) {
+ if (state instanceof SegmentPropertyState) {
+ return getSegmentId((SegmentPropertyState) state);
+ }
+
+ return null;
+ }
+
+ String getTemplateRecordId(NodeState state) {
+ if (state instanceof SegmentNodeState) {
+ return getTemplateRecordId((SegmentNodeState) state);
+ }
+
+ return null;
+ }
+
+ UUID getTemplateSegmentId(NodeState state) {
+ if (state instanceof SegmentNodeState) {
+ return getTemplateSegmentId((SegmentNodeState) state);
+ }
+
+ return null;
+ }
+
+ String getFile(NodeState state) {
+ if (state instanceof SegmentNodeState) {
+ return getFile((SegmentNodeState) state);
+ }
+
+ return null;
+ }
+
+ String getFile(PropertyState state) {
+ if (state instanceof SegmentPropertyState) {
+ return getFile((SegmentPropertyState) state);
+ }
+
+ return null;
+ }
+
+ String getTemplateFile(NodeState state) {
+ if (state instanceof SegmentNodeState) {
+ return getTemplateFile((SegmentNodeState) state);
+ }
+
+ return null;
+ }
+
+ Map<UUID, String> getBulkSegmentIds(Blob blob) {
+ Map<UUID, String> result = Maps.newHashMap();
+
+ for (SegmentId segmentId : SegmentBlob.getBulkSegmentIds(blob)) {
+ result.put(segmentId.asUUID(), getFile(segmentId));
+ }
+
+ return result;
+ }
+
+ String getPersistedCompactionMapStats() {
+ return new PCMAnalyser(store).toString();
+ }
+
+ boolean isExternal(Blob blob) {
+ if (blob instanceof SegmentBlob) {
+ return isExternal((SegmentBlob) blob);
+ }
+
+ return false;
+ }
+
+ private boolean isExternal(SegmentBlob blob) {
+ return blob.isExternal();
+ }
+
+ private String getRecordId(SegmentNodeState state) {
+ return state.getRecordId().toString();
+ }
+
+ private UUID getSegmentId(SegmentNodeState state) {
+ return state.getRecordId().getSegmentId().asUUID();
+ }
+
+ private String getRecordId(SegmentPropertyState state) {
+ return state.getRecordId().toString();
+ }
+
+ private UUID getSegmentId(SegmentPropertyState state) {
+ return state.getRecordId().getSegmentId().asUUID();
+ }
+
+ private String getTemplateRecordId(SegmentNodeState state) {
+ RecordId recordId = SegmentNodeStateHelper.getTemplateId(state);
+
+ if (recordId == null) {
+ return null;
+ }
+
+ return recordId.toString();
+ }
+
+ private UUID getTemplateSegmentId(SegmentNodeState state) {
+ RecordId recordId = SegmentNodeStateHelper.getTemplateId(state);
+
+ if (recordId == null) {
+ return null;
+ }
+
+ return recordId.getSegmentId().asUUID();
+ }
+
+ private String getFile(SegmentNodeState state) {
+ return getFile(state.getRecordId().getSegmentId());
+ }
+
+ private String getFile(SegmentPropertyState state) {
+ return getFile(state.getRecordId().getSegmentId());
+ }
+
+ private String getTemplateFile(SegmentNodeState state) {
+ RecordId recordId = SegmentNodeStateHelper.getTemplateId(state);
+
+ if (recordId == null) {
+ return null;
+ }
+
+ return getFile(recordId.getSegmentId());
+ }
+
+ private String getFile(SegmentId segmentId) {
+ for (Entry<String, Set<UUID>> path2Uuid : index.entrySet()) {
+ for (UUID uuid : path2Uuid.getValue()) {
+ if (uuid.equals(segmentId.asUUID())) {
+ return new File(path2Uuid.getKey()).getName();
+ }
+ }
+ }
+ return null;
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/FileStoreWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/NodeStoreTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/NodeStoreTree.java?rev=1745235&r1=1745234&r2=1745235&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/NodeStoreTree.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer/NodeStoreTree.java Mon May 23 16:35:43 2016
@@ -34,27 +34,18 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
import static org.apache.jackrabbit.oak.commons.json.JsopBuilder.prettyPrint;
import static org.apache.jackrabbit.oak.json.JsopDiff.diffToJsop;
-import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.getGcRoots;
-import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.getTarFiles;
-import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.newline;
-import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.printGcRoots;
-import static org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStateHelper.getTemplateId;
-import java.awt.GridLayout;
+import java.awt.*;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.JTree;
+import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -63,41 +54,91 @@ import javax.swing.tree.DefaultTreeModel
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.plugins.segment.PCMAnalyser;
-import org.apache.jackrabbit.oak.plugins.segment.RecordId;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentBlob;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentNotFoundException;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentPropertyState;
-import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
-import org.apache.jackrabbit.oak.plugins.segment.file.FileStore.ReadOnlyStore;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-public class NodeStoreTree extends JPanel implements TreeSelectionListener,
- Closeable {
+public class NodeStoreTree extends JPanel implements TreeSelectionListener, Closeable {
private static final long serialVersionUID = 1L;
- private final static int MAX_CHAR_DISPLAY = Integer.getInteger(
- "max.char.display", 60);
+ private final static int MAX_CHAR_DISPLAY = Integer.getInteger("max.char.display", 60);
+
+ private static final String newline = "\n";
+
+ private static void printGcRoots(StringBuilder sb, Map<UUID, Set<Entry<UUID, String>>> links, UUID uuid, String space, String inc) {
+ Set<Entry<UUID, String>> roots = links.remove(uuid);
+
+ if (roots == null || roots.isEmpty()) {
+ return;
+ }
+
+ // TODO is sorting by file name needed?
+ for (Entry<UUID, String> r : roots) {
+ sb.append(space).append(r.getKey()).append("[").append(r.getValue()).append("]").append(newline);
+ printGcRoots(sb, links, r.getKey(), space + inc, inc);
+ }
+ }
+
+ private static void printPaths(List<String> paths, StringBuilder sb) {
+ if (paths.isEmpty()) {
+ return;
+ }
+
+ sb.append("Repository content references:").append(newline);
+
+ for (String p : paths) {
+ sb.append(p).append(newline);
+ }
+ }
+
+ private static void printPropertyState(FileStoreWrapper store, PropertyState state, String parentFile, StringBuilder b) {
+ if (store.isPersisted(state)) {
+ printRecordId(store.getRecordId(state), store.getFile(state), parentFile, b);
+ } else {
+ printSimpleClassName(state, b);
+ }
+ }
+
+ private static void printNodeState(FileStoreWrapper store, NodeState state, String parentTarFile, StringBuilder b) {
+ if (store.isPersisted(state)) {
+ printRecordId(store.getRecordId(state), store.getFile(state), parentTarFile, b);
+ } else {
+ printSimpleClassName(state, b);
+ }
+ }
+
+ private static void printRecordId(String recordId, String file, String parentFile, StringBuilder l) {
+ l.append(" (").append(recordId);
+
+ if (file != null && !file.equals(parentFile)) {
+ l.append(" in ").append(file);
+ }
+
+ l.append(")");
+ }
+
+ private static void printSimpleClassName(Object o, StringBuilder l) {
+ l.append(" (").append(o.getClass().getSimpleName()).append(")");
+ }
+
+ private final FileStoreWrapper store;
- private final File path;
- private ReadOnlyStore store;
private Map<String, Set<UUID>> index;
private DefaultTreeModel treeModel;
+
private final JTree tree;
+
private final JTextArea log;
- private Map<RecordIdKey, Long[]> sizeCache;
+ private Map<String, Long[]> sizeCache;
+
private final boolean skipSizeCheck;
- public NodeStoreTree(File path, JTextArea log, boolean skipSizeCheck)
+ NodeStoreTree(FileStoreWrapper store, JTextArea log, boolean skipSizeCheck)
throws IOException {
super(new GridLayout(1, 0));
- this.path = path;
+ this.store = store;
this.log = log;
this.skipSizeCheck = skipSizeCheck;
@@ -115,7 +156,7 @@ public class NodeStoreTree extends JPane
}
private void refreshStore() throws IOException {
- this.store = FileStore.builder(path).buildReadOnly();
+ store.open();
}
private void refreshModel() {
@@ -129,7 +170,7 @@ public class NodeStoreTree extends JPane
tree.setModel(treeModel);
}
- public void reopen() throws IOException {
+ void reopen() throws IOException {
close();
refreshStore();
refreshModel();
@@ -155,10 +196,10 @@ public class NodeStoreTree extends JPane
NamePathModel model = (NamePathModel) node.getUserObject();
NodeState state = model.getState();
- if (state instanceof SegmentNodeState) {
- SegmentNodeState sns = (SegmentNodeState) state;
+ String recordId = store.getRecordId(state);
+ if (recordId != null) {
sb.append("Record ");
- sb.append(sns.getRecordId().toString());
+ sb.append(recordId);
sb.append(newline);
}
setText(sb.toString());
@@ -202,22 +243,21 @@ public class NodeStoreTree extends JPane
NodeState state = model.getState();
String tarFile = "";
- if (state instanceof SegmentNodeState) {
- SegmentNodeState s = (SegmentNodeState) state;
- RecordId recordId = s.getRecordId();
- sb.append("Record " + recordId);
- tarFile = getFile(recordId);
- if (tarFile.length() > 0) {
- sb.append(" in " + tarFile);
+ if (store.isPersisted(state)) {
+ String recordId = store.getRecordId(state);
+ sb.append("Record ").append(recordId);
+ tarFile = store.getFile(state);
+ if (tarFile != null) {
+ sb.append(" in ").append(tarFile);
}
sb.append(newline);
- RecordId templateId = getTemplateId(s);
- String f = getFile(templateId);
+ String templateId = store.getTemplateRecordId(state);
+ String f = store.getTemplateFile(state);
sb.append("TemplateId ");
sb.append(templateId);
- if (!f.equals(tarFile)) {
- sb.append(" in " + f);
+ if (f != null && !f.equals(tarFile)) {
+ sb.append(" in ").append(f);
}
sb.append(newline);
}
@@ -229,15 +269,15 @@ public class NodeStoreTree extends JPane
sb.append(byteCountToDisplaySize(model.getSize()[1]));
sb.append(newline);
- sb.append("Properties (count: " + state.getPropertyCount() + ")");
+ sb.append("Properties (count: ").append(state.getPropertyCount()).append(")");
sb.append(newline);
Map<String, String> propLines = newTreeMap();
for (PropertyState ps : state.getProperties()) {
StringBuilder l = new StringBuilder();
- l.append(" - " + ps.getName() + " = {" + ps.getType() + "} ");
+ l.append(" - ").append(ps.getName()).append(" = {").append(ps.getType()).append("} ");
if (ps.getType().isArray()) {
int count = ps.count();
- l.append("(count " + count + ") [");
+ l.append("(count ").append(count).append(") [");
String separator = ", ";
int max = 50;
@@ -253,7 +293,7 @@ public class NodeStoreTree extends JPane
l.append(toString(ps, i, tarFile));
}
if (count > max) {
- l.append(", ... (" + count + " values)");
+ l.append(", ... (").append(count).append(" values)");
}
if (ps.getType() == Type.BINARIES) {
l.append(separator);
@@ -263,17 +303,7 @@ public class NodeStoreTree extends JPane
} else {
l.append(toString(ps, 0, tarFile));
}
- if (ps instanceof SegmentPropertyState) {
- RecordId rid = ((SegmentPropertyState) ps).getRecordId();
- l.append(" (" + rid);
- String f = getFile(rid);
- if (!f.equals(tarFile)) {
- l.append(" in " + f);
- }
- l.append(")");
- } else {
- l.append(" (" + ps.getClass().getSimpleName() + ")");
- }
+ printPropertyState(store, ps, tarFile, l);
propLines.put(ps.getName(), l.toString());
}
@@ -282,25 +312,14 @@ public class NodeStoreTree extends JPane
sb.append(newline);
}
- sb.append("Child nodes (count: "
- + state.getChildNodeCount(Long.MAX_VALUE) + ")");
+ sb.append("Child nodes (count: ").append(state.getChildNodeCount(Long.MAX_VALUE)).append(")");
sb.append(newline);
Map<String, String> childLines = newTreeMap();
for (ChildNodeEntry ce : state.getChildNodeEntries()) {
StringBuilder l = new StringBuilder();
- l.append(" + " + ce.getName());
+ l.append(" + ").append(ce.getName());
NodeState c = ce.getNodeState();
- if (c instanceof SegmentNodeState) {
- RecordId rid = ((SegmentNodeState) c).getRecordId();
- l.append(" (" + rid);
- String f = getFile(rid);
- if (!f.equals(tarFile)) {
- l.append(" in " + f);
- }
- l.append(")");
- } else {
- l.append(" (" + c.getClass().getSimpleName() + ")");
- }
+ printNodeState(store, c, tarFile, l);
childLines.put(ce.getName(), l.toString());
}
for (String l : childLines.values()) {
@@ -312,7 +331,7 @@ public class NodeStoreTree extends JPane
sb.append("File Reader Index");
sb.append(newline);
- for (String path : getTarFiles(store)) {
+ for (String path : store.getTarFiles()) {
sb.append(path);
sb.append(newline);
}
@@ -330,11 +349,11 @@ public class NodeStoreTree extends JPane
info += "ref:" + safeGetReference(b) + ";";
info += "id:" + b.getContentIdentity() + ";";
info += safeGetLength(b) + ">";
- for (SegmentId sid : SegmentBlob.getBulkSegmentIds(b)) {
- info += newline + " Bulk Segment Id " + sid;
- String f = getFile(sid);
- if (!f.equals(tarFile)) {
- info += " in " + f;
+
+ for (Entry<UUID, String> e : store.getBulkSegmentIds(b).entrySet()) {
+ info += newline + " Bulk Segment Id " + e.getKey();
+ if (e.getValue() != null && !e.getValue().equals(tarFile)) {
+ info += " in " + e.getValue();
}
}
@@ -375,22 +394,7 @@ public class NodeStoreTree extends JPane
return "[BlobStore not available]";
}
- private String getFile(RecordId id) {
- return getFile(id.getSegmentId());
- }
-
- private String getFile(SegmentId segmentId) {
- for (Entry<String, Set<UUID>> path2Uuid : index.entrySet()) {
- for (UUID uuid : path2Uuid.getValue()) {
- if (uuid.equals(segmentId.asUUID())) {
- return new File(path2Uuid.getKey()).getName();
- }
- }
- }
- return "";
- }
-
- public void printTarInfo(String file) {
+ void printTarInfo(String file) {
if (file == null || file.length() == 0) {
return;
}
@@ -399,15 +403,14 @@ public class NodeStoreTree extends JPane
Set<UUID> uuids = newHashSet();
for (Entry<String, Set<UUID>> e : index.entrySet()) {
if (e.getKey().endsWith(file)) {
- sb.append("SegmentNodeState references to "
- + new File(e.getKey()).getName());
+ sb.append("SegmentNodeState references to ").append(new File(e.getKey()).getName());
sb.append(newline);
uuids = e.getValue();
break;
}
}
- Set<UUID> inMem = intersection(getReferencedUUIDs(store), uuids);
+ Set<UUID> inMem = intersection(store.getReferencedSegmentIds(), uuids);
if (!inMem.isEmpty()) {
sb.append("In Memory segment references: ");
sb.append(newline);
@@ -416,15 +419,8 @@ public class NodeStoreTree extends JPane
}
List<String> paths = newArrayList();
- filterNodeStates(uuids, paths, store.getHead(), "/");
- if (!paths.isEmpty()) {
- sb.append("Repository content references:");
- sb.append(newline);
- for (String p : paths) {
- sb.append(p);
- sb.append(newline);
- }
- }
+ filterNodeStates(uuids, paths, store.getHead(), "/", store);
+ printPaths(paths, sb);
sb.append(newline);
try {
@@ -442,15 +438,7 @@ public class NodeStoreTree extends JPane
setText(sb.toString());
}
- private static Set<UUID> getReferencedUUIDs(FileStore store) {
- Set<UUID> ids = newHashSet();
- for (SegmentId id : store.getTracker().getReferencedSegmentIds()) {
- ids.add(id.asUUID());
- }
- return ids;
- }
-
- public void printSegmentReferences(String sid) {
+ void printSegmentReferences(String sid) {
if (sid == null || sid.length() == 0) {
return;
}
@@ -462,30 +450,23 @@ public class NodeStoreTree extends JPane
return;
}
StringBuilder sb = new StringBuilder();
- sb.append("References to segment " + id);
+ sb.append("References to segment ").append(id);
sb.append(newline);
for (Entry<String, Set<UUID>> e : index.entrySet()) {
if (e.getValue().contains(id)) {
- sb.append("Tar file: " + new File(e.getKey()).getName());
+ sb.append("Tar file: ").append(new File(e.getKey()).getName());
sb.append(newline);
break;
}
}
List<String> paths = newArrayList();
- filterNodeStates(newHashSet(id), paths, store.getHead(), "/");
- if (!paths.isEmpty()) {
- sb.append("Repository content references:");
- sb.append(newline);
- for (String p : paths) {
- sb.append(p);
- sb.append(newline);
- }
- }
+ filterNodeStates(newHashSet(id), paths, store.getHead(), "/", store);
+ printPaths(paths, sb);
Map<UUID, Set<Entry<UUID, String>>> links = newHashMap();
try {
- getGcRoots(store, id, links);
+ store.getGcRoots(id, links);
} catch (IOException e) {
sb.append(newline);
sb.append(e.getMessage());
@@ -499,14 +480,12 @@ public class NodeStoreTree extends JPane
setText(sb.toString());
}
- public static void filterNodeStates(Set<UUID> uuids, List<String> paths,
- SegmentNodeState state, String path) {
+ private static void filterNodeStates(Set<UUID> uuids, List<String> paths, NodeState state, String path, FileStoreWrapper store) {
Set<String> localPaths = newTreeSet();
for (PropertyState ps : state.getProperties()) {
- if (ps instanceof SegmentPropertyState) {
- SegmentPropertyState sps = (SegmentPropertyState) ps;
- RecordId recordId = sps.getRecordId();
- UUID id = recordId.getSegmentId().asUUID();
+ if (store.isPersisted(ps)) {
+ String recordId = store.getRecordId(ps);
+ UUID id = store.getSegmentId(ps);
if (uuids.contains(id)) {
if (ps.getType().tag() == STRING) {
String val = "";
@@ -527,9 +506,8 @@ public class NodeStoreTree extends JPane
// look for extra segment references
for (int i = 0; i < ps.count(); i++) {
Blob b = ps.getValue(Type.BINARY, i);
- for (SegmentId sbid : SegmentBlob.getBulkSegmentIds(b)) {
- UUID bid = sbid.asUUID();
- if (!bid.equals(id) && uuids.contains(bid)) {
+ for (Entry<UUID, String> e : store.getBulkSegmentIds(b).entrySet()) {
+ if (!e.getKey().equals(id) && uuids.contains(e.getKey())) {
localPaths.add(path + ps
+ " [SegmentPropertyState<"
+ ps.getType() + ">@" + recordId + "]");
@@ -540,48 +518,38 @@ public class NodeStoreTree extends JPane
}
}
- RecordId stateId = state.getRecordId();
- if (uuids.contains(stateId.getSegmentId().asUUID())) {
+ String stateId = store.getRecordId(state);
+ if (uuids.contains(store.getSegmentId(state))) {
localPaths.add(path + " [SegmentNodeState@" + stateId + "]");
}
- RecordId templateId = getTemplateId(state);
- if (uuids.contains(templateId.getSegmentId().asUUID())) {
+ String templateId = store.getTemplateRecordId(state);
+ if (uuids.contains(store.getTemplateSegmentId(state))) {
localPaths.add(path + "[Template@" + templateId + "]");
}
paths.addAll(localPaths);
for (ChildNodeEntry ce : state.getChildNodeEntries()) {
- NodeState c = ce.getNodeState();
- if (c instanceof SegmentNodeState) {
- filterNodeStates(uuids, paths, (SegmentNodeState) c,
- path + ce.getName() + "/");
- }
+ filterNodeStates(uuids, paths, ce.getNodeState(), path + ce.getName() + "/", store);
}
}
- public void printDiff(String input) {
+ void printDiff(String input) {
StringBuilder sb = new StringBuilder();
if (input == null || input.trim().length() == 0) {
- sb.append("Unknown argument: ");
- sb.append(input);
- sb.append(newline);
setText("Usage <recordId> <recordId> [<path>]");
return;
}
String[] tokens = input.trim().split(" ");
if (tokens.length != 2 && tokens.length != 3) {
- sb.append("Unknown argument: ");
- sb.append(input);
- sb.append(newline);
setText("Usage <recordId> <recordId> [<path>]");
return;
}
- RecordId id1 = null;
- RecordId id2 = null;
+ NodeState node1;
+ NodeState node2;
try {
- id1 = RecordId.fromString(store.getTracker(), tokens[0]);
- id2 = RecordId.fromString(store.getTracker(), tokens[1]);
+ node1 = store.readNodeState(tokens[0]);
+ node2 = store.readNodeState(tokens[1]);
} catch (IllegalArgumentException ex) {
sb.append("Unknown argument: ");
sb.append(input);
@@ -597,17 +565,15 @@ public class NodeStoreTree extends JPane
path = tokens[2];
}
- NodeState node1 = new SegmentNodeState(id1);
- NodeState node2 = new SegmentNodeState(id2);
for (String name : elements(path)) {
node1 = node1.getChildNode(name);
node2 = node2.getChildNode(name);
}
sb.append("SegmentNodeState diff ");
- sb.append(id1);
+ sb.append(tokens[0]);
sb.append(" vs ");
- sb.append(id2);
+ sb.append(tokens[1]);
sb.append(" at ");
sb.append(path);
sb.append(newline);
@@ -617,19 +583,19 @@ public class NodeStoreTree extends JPane
setText(sb.toString());
}
- public boolean revert(String revision) {
+ boolean revert(String revision) {
return safeRevert(revision, false);
}
private boolean safeRevert(String revision, boolean rollback) {
- String head = store.getHead().getRecordId().toString();
+ String head = store.getRecordId(store.getHead());
store.setRevision(revision);
try {
refreshModel();
if (!rollback) {
setText("Switched head revision to " + revision);
}
- } catch (SegmentNotFoundException e) {
+ } catch (Exception e) {
StringBuilder sb = new StringBuilder();
sb.append("Unable to switch head revision to ");
sb.append(revision);
@@ -642,44 +608,39 @@ public class NodeStoreTree extends JPane
setText(sb.toString());
return safeRevert(head, true);
}
- if (rollback) {
- return false;
- }
- return true;
+ return !rollback;
}
- public void printPCMInfo() {
- setText(new PCMAnalyser(store).toString());
+ void printPCMInfo() {
+ setText(store.getPersistedCompactionMapStats());
}
private static class NamePathModel implements Comparable<NamePathModel> {
- private final FileStore store;
+ private final FileStoreWrapper store;
private final String name;
private final String path;
private final boolean skipSizeCheck;
private boolean loaded = false;
- private Long[] size = { -1l, -1l };
+ private Long[] size = {-1L, -1L};
- public NamePathModel(String name, String path, NodeState state,
- Map<RecordIdKey, Long[]> sizeCache, boolean skipSizeCheck,
- FileStore store) {
+ NamePathModel(String name, String path, NodeState state, Map<String, Long[]> sizeCache, boolean skipSizeCheck, FileStoreWrapper store) {
this.store = store;
this.name = name;
this.path = path;
this.skipSizeCheck = skipSizeCheck;
- if (!skipSizeCheck && state instanceof SegmentNodeState) {
- this.size = exploreSize((SegmentNodeState) state, sizeCache);
+ if (!skipSizeCheck && store.isPersisted(state)) {
+ this.size = exploreSize(state, sizeCache, store);
}
}
- public void loaded() {
+ void loaded() {
loaded = true;
}
- public boolean isLoaded() {
+ boolean isLoaded() {
return loaded;
}
@@ -737,13 +698,12 @@ public class NodeStoreTree extends JPane
}
}
- private static Long[] exploreSize(SegmentNodeState ns,
- Map<RecordIdKey, Long[]> sizeCache) {
- RecordIdKey key = new RecordIdKey(ns.getRecordId());
+ private static Long[] exploreSize(NodeState ns, Map<String, Long[]> sizeCache, FileStoreWrapper store) {
+ String key = store.getRecordId(ns);
if (sizeCache.containsKey(key)) {
return sizeCache.get(key);
}
- Long[] s = { 0l, 0l };
+ Long[] s = {0L, 0L};
List<String> names = newArrayList(ns.getChildNodeNames());
@@ -751,9 +711,7 @@ public class NodeStoreTree extends JPane
List<String> temp = newArrayList();
int poz = 0;
// push 'root' to the beginning
- Iterator<String> iterator = names.iterator();
- while (iterator.hasNext()) {
- String n = iterator.next();
+ for (String n : names) {
if (n.equals("root")) {
temp.add(poz, n);
poz++;
@@ -765,14 +723,14 @@ public class NodeStoreTree extends JPane
}
for (String n : names) {
- SegmentNodeState k = (SegmentNodeState) ns.getChildNode(n);
- RecordIdKey ckey = new RecordIdKey(k.getRecordId());
+ NodeState k = ns.getChildNode(n);
+ String ckey = store.getRecordId(k);
if (sizeCache.containsKey(ckey)) {
// already been here, record size under 'link'
Long[] ks = sizeCache.get(ckey);
s[1] = s[1] + ks[0] + ks[1];
} else {
- Long[] ks = exploreSize(k, sizeCache);
+ Long[] ks = exploreSize(k, sizeCache, store);
s[0] = s[0] + ks[0];
s[1] = s[1] + ks[1];
}
@@ -781,8 +739,7 @@ public class NodeStoreTree extends JPane
for (int j = 0; j < ps.count(); j++) {
if (ps.getType().tag() == Type.BINARY.tag()) {
Blob b = ps.getValue(Type.BINARY, j);
- boolean skip = b instanceof SegmentBlob
- && ((SegmentBlob) b).isExternal();
+ boolean skip = store.isExternal(b);
if (!skip) {
s[0] = s[0] + b.length();
}
@@ -795,38 +752,6 @@ public class NodeStoreTree extends JPane
return s;
}
- private static class RecordIdKey {
-
- private final long msb;
- private final long lsb;
- private final int offset;
-
- public RecordIdKey(RecordId rid) {
- this.offset = rid.getOffset();
- this.msb = rid.getSegmentId().getMostSignificantBits();
- this.lsb = rid.getSegmentId().getLeastSignificantBits();
- }
-
- @Override
- public boolean equals(Object object) {
- if (this == object) {
- return true;
- } else if (object instanceof RecordIdKey) {
- RecordIdKey that = (RecordIdKey) object;
- return offset == that.offset && msb == that.msb
- && lsb == that.lsb;
- } else {
- return false;
- }
- }
-
- @Override
- public int hashCode() {
- return ((int) lsb) ^ offset;
- }
-
- }
-
@Override
public void close() throws IOException {
store.close();
Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentUtils.java?rev=1745235&r1=1745234&r2=1745235&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentUtils.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/SegmentUtils.java Mon May 23 16:35:43 2016
@@ -18,6 +18,10 @@
package org.apache.jackrabbit.oak.run;
import static com.google.common.collect.Sets.newHashSet;
+import static com.google.common.collect.Sets.newTreeSet;
+import static com.google.common.escape.Escapers.builder;
+import static javax.jcr.PropertyType.BINARY;
+import static javax.jcr.PropertyType.STRING;
import static org.apache.commons.io.FileUtils.byteCountToDisplaySize;
import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.newBasicReadOnlyBlobStore;
import static org.apache.jackrabbit.oak.plugins.segment.FileStoreHelper.openFileStore;
@@ -25,6 +29,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.segment.RecordType.NODE;
import static org.apache.jackrabbit.oak.plugins.segment.SegmentGraph.writeGCGraph;
import static org.apache.jackrabbit.oak.plugins.segment.SegmentGraph.writeSegmentGraph;
+import static org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStateHelper.getTemplateId;
import static org.apache.jackrabbit.oak.plugins.segment.file.tooling.ConsistencyChecker.checkConsistency;
import static org.apache.jackrabbit.oak.run.Utils.asCloseable;
import static org.slf4j.LoggerFactory.getLogger;
@@ -53,6 +58,9 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Queues;
import com.google.common.io.Closer;
import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.IOUtils;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
@@ -64,19 +72,24 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.segment.RecordId;
import org.apache.jackrabbit.oak.plugins.segment.RecordUsageAnalyser;
import org.apache.jackrabbit.oak.plugins.segment.Segment;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentBlob;
import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentPropertyState;
import org.apache.jackrabbit.oak.plugins.segment.SegmentTracker;
import org.apache.jackrabbit.oak.plugins.segment.compaction.CompactionStrategy;
import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
import org.apache.jackrabbit.oak.plugins.segment.file.JournalReader;
import org.apache.jackrabbit.oak.plugins.segment.file.tooling.RevisionHistory;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
class SegmentUtils {
+ private final static int MAX_CHAR_DISPLAY = Integer.getInteger("max.char.display", 60);
+
private SegmentUtils() {
// Prevent instantiation
}
@@ -315,7 +328,7 @@ class SegmentUtils {
if (hasrefs) {
System.out.println("SegmentNodeState references to " + f);
List<String> paths = new ArrayList<String>();
- NodeStoreTree.filterNodeStates(uuids, paths, store.getHead(),
+ filterNodeStates(uuids, paths, store.getHead(),
"/");
for (String p : paths) {
System.out.println(" " + p);
@@ -392,5 +405,75 @@ class SegmentUtils {
}
}
}
+
+ private static String displayString(String value) {
+ if (MAX_CHAR_DISPLAY > 0 && value.length() > MAX_CHAR_DISPLAY) {
+ value = value.substring(0, MAX_CHAR_DISPLAY) + "... ("
+ + value.length() + " chars)";
+ }
+ String escaped = builder().setSafeRange(' ', '~')
+ .addEscape('"', "\\\"").addEscape('\\', "\\\\").build()
+ .escape(value);
+ return '"' + escaped + '"';
+ }
+
+ private static void filterNodeStates(Set<UUID> uuids, List<String> paths, SegmentNodeState state, String path) {
+ Set<String> localPaths = newTreeSet();
+ for (PropertyState ps : state.getProperties()) {
+ if (ps instanceof SegmentPropertyState) {
+ SegmentPropertyState sps = (SegmentPropertyState) ps;
+ RecordId recordId = sps.getRecordId();
+ UUID id = recordId.getSegmentId().asUUID();
+ if (uuids.contains(id)) {
+ if (ps.getType().tag() == STRING) {
+ String val = "";
+ if (ps.count() > 0) {
+ // only shows the first value, do we need more?
+ val = displayString(ps.getValue(Type.STRING, 0));
+ }
+ localPaths.add(path + ps.getName() + " = " + val
+ + " [SegmentPropertyState<" + ps.getType()
+ + ">@" + recordId + "]");
+ } else {
+ localPaths.add(path + ps + " [SegmentPropertyState<"
+ + ps.getType() + ">@" + recordId + "]");
+ }
+
+ }
+ if (ps.getType().tag() == BINARY) {
+ // look for extra segment references
+ for (int i = 0; i < ps.count(); i++) {
+ Blob b = ps.getValue(Type.BINARY, i);
+ for (SegmentId sbid : SegmentBlob.getBulkSegmentIds(b)) {
+ UUID bid = sbid.asUUID();
+ if (!bid.equals(id) && uuids.contains(bid)) {
+ localPaths.add(path + ps
+ + " [SegmentPropertyState<"
+ + ps.getType() + ">@" + recordId + "]");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ RecordId stateId = state.getRecordId();
+ if (uuids.contains(stateId.getSegmentId().asUUID())) {
+ localPaths.add(path + " [SegmentNodeState@" + stateId + "]");
+ }
+
+ RecordId templateId = getTemplateId(state);
+ if (uuids.contains(templateId.getSegmentId().asUUID())) {
+ localPaths.add(path + "[Template@" + templateId + "]");
+ }
+ paths.addAll(localPaths);
+ for (ChildNodeEntry ce : state.getChildNodeEntries()) {
+ NodeState c = ce.getNodeState();
+ if (c instanceof SegmentNodeState) {
+ filterNodeStates(uuids, paths, (SegmentNodeState) c,
+ path + ce.getName() + "/");
+ }
+ }
+ }
}