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