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/05/27 15:55:02 UTC
svn commit: r1597789 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/
oak-run/src/main/java/org/apache/jackrabbit/oak/run/ oak-run/src/m...
Author: alexparvulescu
Date: Tue May 27 13:55:02 2014
New Revision: 1597789
URL: http://svn.apache.org/r1597789
Log:
OAK-1858 Segment Explorer
- first draft
Added:
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentExplorer.java (with props)
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentTree.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java?rev=1597789&r1=1597788&r2=1597789&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentPropertyState.java Tue May 27 13:55:02 2014
@@ -49,7 +49,7 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.api.Type.URI;
import static org.apache.jackrabbit.oak.api.Type.WEAKREFERENCE;
-class SegmentPropertyState extends Record implements PropertyState {
+public class SegmentPropertyState extends Record implements PropertyState {
private final PropertyTemplate template;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1597789&r1=1597788&r2=1597789&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java Tue May 27 13:55:02 2014
@@ -36,6 +36,7 @@ import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileLock;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -591,4 +592,12 @@ public class FileStore implements Segmen
System.gc();
cleanupNeeded.set(true);
}
+
+ public Map<String, Set<UUID>> getTarReaderIndex() {
+ Map<String, Set<UUID>> index = new HashMap<String, Set<UUID>>();
+ for (TarReader reader : readers) {
+ index.put(reader.getFile().getAbsolutePath(), reader.getUUIDs());
+ }
+ return index;
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java?rev=1597789&r1=1597788&r2=1597789&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/TarReader.java Tue May 27 13:55:02 2014
@@ -709,6 +709,10 @@ class TarReader {
return number;
}
+ File getFile(){
+ return file;
+ }
+
//------------------------------------------------------------< Object >--
@Override
Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java?rev=1597789&r1=1597788&r2=1597789&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java Tue May 27 13:55:02 2014
@@ -40,9 +40,11 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Queues;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
+
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
+
import org.apache.jackrabbit.core.RepositoryContext;
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.apache.jackrabbit.oak.Oak;
@@ -63,6 +65,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
import org.apache.jackrabbit.oak.scalability.ScalabilityRunner;
+import org.apache.jackrabbit.oak.segmentexplorer.SegmentExplorer;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStore;
import org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade;
@@ -115,7 +118,10 @@ public class Main {
break;
case SCALABILITY:
ScalabilityRunner.main(args);
- break;
+ break;
+ case EXPLORE:
+ SegmentExplorer.main(args);
+ break;
default:
System.err.println("Unknown command: " + mode);
System.exit(1);
@@ -502,8 +508,9 @@ public class Main {
DEBUG("debug"),
SERVER("server"),
UPGRADE("upgrade"),
- SCALABILITY("scalability");
-
+ SCALABILITY("scalability"),
+ EXPLORE("explore");
+
private final String name;
Mode(String name) {
Added: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentExplorer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentExplorer.java?rev=1597789&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentExplorer.java (added)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentExplorer.java Tue May 27 13:55:02 2014
@@ -0,0 +1,105 @@
+/*
+ * 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.segmentexplorer;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
+
+import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
+
+public class SegmentExplorer {
+
+ public static void main(String[] args) throws IOException {
+ new SegmentExplorer(args);
+ }
+
+ public SegmentExplorer(String[] args) throws IOException {
+ if (args.length == 0) {
+ System.err.println("usage: explore <path> [/content/path...]");
+ System.exit(1);
+ }
+
+ final String path = args[0];
+ final FileStore store = new FileStore(new File(path), 256);
+
+ javax.swing.SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ initLF();
+ createAndShowGUI(path, store);
+ }
+ });
+ }
+
+ 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(String path, FileStore store) {
+ // Create and set up the window.
+ JFrame frame = new JFrame("Explore " + path);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JPanel content = new JPanel(new GridBagLayout());
+
+ JTextArea log = new JTextArea(5, 20);
+ log.setMargin(new Insets(5, 5, 5, 5));
+ log.setLineWrap(true);
+ log.setEditable(false);
+
+ SegmentTree treePanel = new SegmentTree(store, log);
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 1;
+ c.weighty = 1;
+ content.add(new JScrollPane(treePanel), c);
+
+ c.weightx = 3;
+ content.add(new JScrollPane(log), c);
+
+ frame.getContentPane().add(content);
+
+ frame.pack();
+ frame.setSize(800, 600);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentExplorer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentTree.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentTree.java?rev=1597789&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentTree.java (added)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentTree.java Tue May 27 13:55:02 2014
@@ -0,0 +1,356 @@
+/*
+ * 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.segmentexplorer;
+
+import java.awt.GridLayout;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+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.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeSelectionModel;
+
+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.plugins.segment.RecordId;
+import org.apache.jackrabbit.oak.plugins.segment.Segment;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentPropertyState;
+import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import com.google.common.collect.Lists;
+
+public class SegmentTree extends JPanel implements TreeSelectionListener {
+
+ private final FileStore store;
+
+ private final DefaultTreeModel treeModel;
+ private final JTree tree;
+ private final JTextArea log;
+
+ private final Map<String, Set<UUID>> index;
+ private final Map<RecordId, Long[]> sizeCache;
+
+ public SegmentTree(FileStore store, JTextArea log) {
+ super(new GridLayout(1, 0));
+ this.store = store;
+ this.log = log;
+
+ index = store.getTarReaderIndex();
+ sizeCache = new HashMap<RecordId, Long[]>();
+
+ DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(
+ new NamePathModel("/", "/", store.getHead(), sizeCache), true);
+ treeModel = new DefaultTreeModel(rootNode);
+ addChildren(rootNode);
+
+ tree = new JTree(treeModel);
+ tree.getSelectionModel().setSelectionMode(
+ TreeSelectionModel.SINGLE_TREE_SELECTION);
+ tree.setShowsRootHandles(true);
+ tree.addTreeSelectionListener(this);
+ tree.setExpandsSelectedPaths(true);
+
+ JScrollPane scrollPane = new JScrollPane(tree);
+ add(scrollPane);
+ }
+
+ @Override
+ public void valueChanged(TreeSelectionEvent e) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
+ .getLastSelectedPathComponent();
+ if (node == null) {
+ return;
+ }
+ // load child nodes:
+ addChildren(node);
+ updateStats(node);
+ }
+
+ private void addChildren(DefaultMutableTreeNode parent) {
+ NamePathModel model = (NamePathModel) parent.getUserObject();
+ if (model.isLoaded()) {
+ return;
+ }
+
+ List<NamePathModel> kids = new ArrayList<NamePathModel>();
+ for (ChildNodeEntry ce : model.getState().getChildNodeEntries()) {
+ NamePathModel c = new NamePathModel(ce.getName(), PathUtils.concat(
+ model.getPath(), ce.getName()), ce.getNodeState(),
+ sizeCache);
+ kids.add(c);
+ }
+ Collections.sort(kids);
+ for (NamePathModel c : kids) {
+ DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(c,
+ true);
+ treeModel.insertNodeInto(childNode, parent, parent.getChildCount());
+ }
+ model.loaded();
+ }
+
+ private final static String newline = "\n";
+
+ private void updateStats(DefaultMutableTreeNode parent) {
+ NamePathModel model = (NamePathModel) parent.getUserObject();
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(model.getPath());
+ sb.append(newline);
+
+ NodeState state = model.getState();
+
+ if (state instanceof SegmentNodeState) {
+ sb.append("Size: ");
+ sb.append(" direct: ");
+ sb.append(FileUtils.byteCountToDisplaySize(model.getSize()[0]));
+ sb.append("; linked: ");
+ sb.append(FileUtils.byteCountToDisplaySize(model.getSize()[1]));
+ sb.append(newline);
+
+ SegmentNodeState s = (SegmentNodeState) state;
+ Segment segment = s.getRecordId().getSegment();
+ sb.append("Segment ");
+ sb.append(segment.getSegmentId());
+ sb.append(newline);
+
+ sb.append("File ");
+ String file = getFile(segment.getSegmentId().toString());
+ sb.append(file);
+ sb.append(newline);
+
+ sb.append("State");
+ sb.append(newline);
+ sb.append(" Child Node Count: " + s.getChildNodeCount(-1));
+ sb.append(newline);
+ for (ChildNodeEntry ce : s.getChildNodeEntries()) {
+ SegmentNodeState c = (SegmentNodeState) ce.getNodeState();
+ sb.append(" " + c.getRecordId().getSegmentId() + " -> "
+ + ce.getName());
+ sb.append(newline);
+
+ String f = getFile(c.getRecordId().getSegmentId().toString());
+ if (!f.equals(file)) {
+ sb.append(" * " + f);
+ sb.append(newline);
+ }
+ }
+ sb.append(" Property Count: " + s.getPropertyCount());
+ sb.append(newline);
+ for (PropertyState ps : s.getProperties()) {
+ if (ps instanceof SegmentPropertyState) {
+ String val = "";
+ if (ps.getType() == Type.STRING) {
+ val = ps.getValue(Type.STRING);
+ } else if (ps.getType() == Type.NAME) {
+ val = ps.getValue(Type.NAME);
+ } else {
+ val = ps.toString();
+ }
+ // TODO handle the display for the rest of the property
+ // types
+ String sId = ((SegmentPropertyState) ps).getRecordId()
+ .getSegmentId().toString();
+ sb.append(" " + sId + " -> " + ps.getName() + " (" + val
+ + ")");
+ sb.append(newline);
+ String f = getFile(sId);
+ if (!f.equals(file)) {
+ sb.append(" * " + f);
+ sb.append(newline);
+ }
+
+ } else {
+ String val = "";
+ if (ps.getType() == Type.STRING) {
+ val = ps.getValue(Type.STRING);
+ }
+ if (ps.getType() == Type.NAME) {
+ val = ps.getValue(Type.NAME);
+ }
+ sb.append(" " + ps.getName() + " ("
+ + ps.getClass().getSimpleName() + ")" + " (" + val
+ + ")");
+ sb.append(newline);
+ }
+ }
+ }
+
+ if ("/".equals(model.getPath())) {
+ sb.append("File Index");
+ sb.append(newline);
+ for (Entry<String, Set<UUID>> path2Uuid : index.entrySet()) {
+ sb.append(path2Uuid.getKey());
+ sb.append(newline);
+ // sb.append(path2Uuid.getValue());
+ // sb.append(newline);
+ }
+ sb.append("----------");
+ }
+
+ log.setText(sb.toString());
+ }
+
+ private String getFile(String sId) {
+ for (Entry<String, Set<UUID>> path2Uuid : index.entrySet()) {
+ for (UUID uuid : path2Uuid.getValue()) {
+ if (uuid.toString().equals(sId)) {
+ return path2Uuid.getKey();
+ }
+ }
+ }
+ return "";
+ }
+
+ private static class NamePathModel implements Comparable<NamePathModel> {
+
+ private final String name;
+ private final String path;
+ private final NodeState state;
+
+ private boolean loaded = false;
+
+ private Long[] size = { -1l, -1l };
+
+ public NamePathModel(String name, String path, NodeState state,
+ Map<RecordId, Long[]> sizeCache) {
+ this.name = name;
+ this.path = path;
+ this.state = state;
+ if (state instanceof SegmentNodeState) {
+ this.size = exploreSize((SegmentNodeState) state, sizeCache);
+ }
+ }
+
+ public void loaded() {
+ loaded = true;
+ }
+
+ public boolean isLoaded() {
+ return loaded;
+ }
+
+ @Override
+ public String toString() {
+ if (size[1] > 0) {
+ return name + " (" + FileUtils.byteCountToDisplaySize(size[0])
+ + ";" + FileUtils.byteCountToDisplaySize(size[1]) + ")";
+ }
+ if (size[0] > 0) {
+ return name + " (" + FileUtils.byteCountToDisplaySize(size[0])
+ + ")";
+ }
+ return name;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public NodeState getState() {
+ return state;
+ }
+
+ @Override
+ public int compareTo(NamePathModel o) {
+ int s = size[0].compareTo(o.size[0]);
+ if (s != 0) {
+ return -1 * s;
+ }
+ s = size[1].compareTo(o.size[1]);
+ if (s != 0) {
+ return -1 * s;
+ }
+ if ("root".equals(name)) {
+ return 1;
+ } else if ("root".equals(o.name)) {
+ return -1;
+ }
+ return name.compareTo(o.name);
+ }
+
+ public Long[] getSize() {
+ return size;
+ }
+ }
+
+ private static Long[] exploreSize(SegmentNodeState ns,
+ Map<RecordId, Long[]> sizeCache) {
+ if (sizeCache.containsKey(ns.getRecordId())) {
+ return sizeCache.get(ns.getRecordId());
+ }
+ Long[] s = { 0l, 0l };
+
+ List<String> names = Lists.newArrayList(ns.getChildNodeNames());
+
+ if (names.contains("root")) {
+ List<String> temp = Lists.newArrayList();
+ int poz = 0;
+ // push 'root' to the beginning
+ Iterator<String> iterator = names.iterator();
+ while (iterator.hasNext()) {
+ String n = iterator.next();
+ if (n.equals("root")) {
+ temp.add(poz, n);
+ poz++;
+ } else {
+ temp.add(n);
+ }
+ }
+ names = temp;
+ }
+
+ for (String n : names) {
+ SegmentNodeState k = (SegmentNodeState) ns.getChildNode(n);
+ if (sizeCache.containsKey(k.getRecordId())) {
+ // already been here, record size under 'link'
+ Long[] ks = sizeCache.get(k.getRecordId());
+ s[1] = s[1] + ks[0] + ks[1];
+ } else {
+ Long[] ks = exploreSize(k, sizeCache);
+ s[0] = s[0] + ks[0];
+ s[1] = s[1] + ks[1];
+ }
+ }
+ for (PropertyState ps : ns.getProperties()) {
+ for (int j = 0; j < ps.count(); j++) {
+ s[0] = s[0] + ps.size(j);
+ }
+ }
+ sizeCache.put(ns.getRecordId(), s);
+ return s;
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/segmentexplorer/SegmentTree.java
------------------------------------------------------------------------------
svn:eol-style = native