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 al...@apache.org on 2014/06/09 16:57:42 UTC
svn commit: r1601403 - in
/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/explorer:
Explorer.java NodeStoreTree.java
Author: alexparvulescu
Date: Mon Jun 9 14:57:41 2014
New Revision: 1601403
URL: http://svn.apache.org/r1601403
Log:
OAK-1858 Segment Explorer
- properly close the store on exit
- added option to run compaction, run the diff between 2 node states, and to trace the node store references to a specific file (wip)
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
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=1601403&r1=1601402&r2=1601403&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 Jun 9 14:57:41 2014
@@ -21,12 +21,21 @@ package org.apache.jackrabbit.oak.explor
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
import java.io.File;
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;
@@ -77,9 +86,15 @@ public class Explorer {
}
}
- private void createAndShowGUI(String path, FileStore store) {
- JFrame frame = new JFrame("Explore " + path);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ private void createAndShowGUI(final String path, final FileStore store) {
+ final JFrame frame = new JFrame("Explore " + path);
+ frame.addWindowListener(new java.awt.event.WindowAdapter() {
+ @Override
+ public void windowClosing(java.awt.event.WindowEvent windowEvent) {
+ store.close();
+ System.exit(0);
+ }
+ });
JPanel content = new JPanel(new GridBagLayout());
@@ -88,7 +103,7 @@ public class Explorer {
log.setLineWrap(true);
log.setEditable(false);
- NodeStoreTree treePanel = new NodeStoreTree(store, log);
+ final NodeStoreTree treePanel = new NodeStoreTree(store, log);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
@@ -99,9 +114,71 @@ public class Explorer {
new JScrollPane(treePanel), new JScrollPane(log));
splitPane.setDividerLocation(0.3);
content.add(new JScrollPane(splitPane), c);
-
frame.getContentPane().add(content);
+ JMenuBar menuBar = new JMenuBar();
+ menuBar.setMargin(new Insets(2, 2, 2, 2));
+
+ JMenuItem menuCompaction = new JMenuItem("Tar Compaction");
+ menuCompaction.setMnemonic(KeyEvent.VK_C);
+ menuCompaction.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent ev) {
+ int run = JOptionPane.showConfirmDialog(frame,
+ "Run compaction on the tar files", "Tar Compaction",
+ JOptionPane.WARNING_MESSAGE, JOptionPane.YES_NO_OPTION);
+ if (run == JOptionPane.YES_OPTION) {
+ treePanel.compact();
+ }
+ }
+ });
+
+ JMenuItem menuRefs = new JMenuItem("Tar File Refs");
+ menuRefs.setMnemonic(KeyEvent.VK_R);
+ menuRefs.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent ev) {
+ List<String> tarFiles = new ArrayList<String>();
+ for (File f : new File(path).listFiles()) {
+ if (f.getName().endsWith(".tar")) {
+ tarFiles.add(f.getName());
+ }
+ }
+
+ String s = (String) JOptionPane.showInputDialog(frame,
+ "Choose a tar file", "Tar File References",
+ JOptionPane.PLAIN_MESSAGE, null, tarFiles.toArray(),
+ tarFiles.get(0));
+ if (s != null) {
+ treePanel.printDependenciesToFile(s);
+ return;
+ }
+ }
+ });
+
+ JMenuItem menuDiff = new JMenuItem("SegmentNodeState diff");
+ menuDiff.setMnemonic(KeyEvent.VK_D);
+ menuDiff.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent ev) {
+ String s = (String) JOptionPane.showInputDialog(frame,
+ "SegmentNodeState diff\nUsage: <recordId> <recordId> [<path>]",
+ "SegmentNodeState diff", JOptionPane.PLAIN_MESSAGE);
+ if (s != null) {
+ treePanel.printDiff(s);
+ return;
+ }
+ }
+ });
+
+ menuBar.add(menuCompaction);
+ menuBar.add(new JSeparator(JSeparator.VERTICAL));
+ menuBar.add(menuRefs);
+ menuBar.add(new JSeparator(JSeparator.VERTICAL));
+ menuBar.add(menuDiff);
+ menuBar.add(new JSeparator(JSeparator.VERTICAL));
+
+ frame.setJMenuBar(menuBar);
frame.pack();
frame.setSize(960, 720);
frame.setLocationRelativeTo(null);
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=1601403&r1=1601402&r2=1601403&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 Jun 9 14:57:41 2014
@@ -20,9 +20,11 @@ package org.apache.jackrabbit.oak.explor
import java.awt.GridLayout;
import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -45,6 +47,8 @@ import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
+import org.apache.jackrabbit.oak.kernel.JsopDiff;
import org.apache.jackrabbit.oak.plugins.segment.RecordId;
import org.apache.jackrabbit.oak.plugins.segment.SegmentId;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
@@ -58,6 +62,8 @@ import com.google.common.escape.Escapers
class NodeStoreTree extends JPanel implements TreeSelectionListener {
+ private final FileStore store;
+
private final DefaultTreeModel treeModel;
private final JTree tree;
private final JTextArea log;
@@ -67,6 +73,7 @@ class NodeStoreTree extends JPanel imple
public NodeStoreTree(FileStore store, JTextArea log) {
super(new GridLayout(1, 0));
+ this.store = store;
this.log = log;
index = store.getTarReaderIndex();
@@ -209,11 +216,14 @@ class NodeStoreTree extends JPanel imple
if ("/".equals(model.getPath())) {
sb.append("File Index");
sb.append(newline);
- for (Entry<String, Set<UUID>> path2Uuid : index.entrySet()) {
- sb.append(path2Uuid.getKey());
+
+ List<String> files = new ArrayList<String>(store
+ .getTarReaderIndex().keySet());
+ Collections.sort(files);
+
+ for (String path : files) {
+ sb.append(path);
sb.append(newline);
- // sb.append(path2Uuid.getValue());
- // sb.append(newline);
}
sb.append("----------");
}
@@ -256,6 +266,152 @@ class NodeStoreTree extends JPanel imple
return "";
}
+ public void printDependenciesToFile(String file) {
+ if (file == null || file.length() == 0) {
+ return;
+ }
+ StringBuilder sb = new StringBuilder();
+
+ Set<UUID> uuids = new HashSet<UUID>();
+ for (Entry<String, Set<UUID>> e : store.getTarReaderIndex().entrySet()) {
+ if (e.getKey().endsWith(file)) {
+ sb.append("SegmentNodeState references to " + e.getKey());
+ sb.append(newline);
+ uuids = e.getValue();
+ }
+ }
+ List<String> paths = new ArrayList<String>();
+ filterNodeStates(uuids, paths, store.getHead(), "/");
+ for (String p : paths) {
+ sb.append(" ");
+ sb.append(p);
+ sb.append(newline);
+ }
+
+ log.setText(sb.toString());
+ }
+
+ private static void filterNodeStates(Set<UUID> uuids, List<String> paths,
+ SegmentNodeState state, String path) {
+ for (PropertyState ps : state.getProperties()) {
+ if (ps instanceof SegmentPropertyState) {
+ SegmentPropertyState sps = (SegmentPropertyState) ps;
+ SegmentId id = sps.getRecordId().getSegmentId();
+ if (contains(id, uuids)) {
+ paths.add(path + "@" + ps);
+ }
+ }
+ }
+ for (ChildNodeEntry ce : state.getChildNodeEntries()) {
+ NodeState c = ce.getNodeState();
+ if (c instanceof SegmentNodeState) {
+ filterNodeStates(uuids, paths, (SegmentNodeState) c,
+ path + ce.getName() + "/");
+ }
+ }
+ }
+
+ private static boolean contains(SegmentId id, Set<UUID> uuids) {
+ for (UUID u : uuids) {
+ if (id.getMostSignificantBits() == u.getMostSignificantBits()
+ && id.getLeastSignificantBits() == u
+ .getLeastSignificantBits()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public 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);
+ log.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);
+ log.setText("Usage <recordId> <recordId> [<path>]");
+ return;
+ }
+ RecordId id1 = null;
+ RecordId id2 = null;
+ try {
+ id1 = RecordId.fromString(store.getTracker(), tokens[0]);
+ id2 = RecordId.fromString(store.getTracker(), tokens[1]);
+ } catch (IllegalArgumentException ex) {
+ sb.append("Unknown argument: ");
+ sb.append(input);
+ sb.append(newline);
+ sb.append("Error: ");
+ sb.append(ex.getMessage());
+ sb.append(newline);
+ log.setText(sb.toString());
+ return;
+ }
+ String path = "/";
+ if (tokens.length == 3) {
+ path = tokens[2];
+ }
+
+ NodeState node1 = new SegmentNodeState(id1);
+ NodeState node2 = new SegmentNodeState(id2);
+ for (String name : PathUtils.elements(path)) {
+ node1 = node1.getChildNode(name);
+ node2 = node2.getChildNode(name);
+ }
+
+ sb.append("SegmentNodeState diff ");
+ sb.append(id1);
+ sb.append(" vs ");
+ sb.append(id2);
+ sb.append(" at ");
+ sb.append(path);
+ sb.append(newline);
+ sb.append("--------");
+ sb.append(newline);
+ sb.append(JsopBuilder.prettyPrint(JsopDiff.diffToJsop(node1, node2)));
+ log.setText(sb.toString());
+ }
+
+ public void compact() {
+ StringBuilder sb = new StringBuilder();
+
+ long s = System.currentTimeMillis();
+ store.gc();
+ store.compact();
+ try {
+ store.flush();
+ } catch (IOException e) {
+ sb.append("IOException " + e.getMessage());
+ e.printStackTrace();
+ }
+ s = System.currentTimeMillis() - s;
+
+ sb.append("Compacted tar segments in " + s + " ms.");
+ sb.append(newline);
+
+ sb.append("File Index");
+ sb.append(newline);
+
+ List<String> files = new ArrayList<String>(store.getTarReaderIndex()
+ .keySet());
+ Collections.sort(files);
+
+ for (String path : files) {
+ sb.append(path);
+ sb.append(newline);
+ }
+ sb.append("----------");
+ log.setText(sb.toString());
+ }
+
private static class NamePathModel implements Comparable<NamePathModel> {
private final String name;