view src/main/java/jp/ac/u_ryukyu/ie/cr/jungleNetwork/persistent/PersistentJungleTree.java @ 263:cac88cf813f1 Implementation_of_communication

tmp
author tatsuki
date Tue, 13 Dec 2016 00:00:18 +0900
parents 33c93f162389
children b3a04bc21b23
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent;


import jp.ac.u_ryukyu.ie.cr.jungle.tree.DefaultJungleTree;
import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
import jp.ac.u_ryukyu.ie.cr.jungle.data.list.List;
import jp.ac.u_ryukyu.ie.cr.jungle.data.treemap.TreeMap;
import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList;
import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeListWriter;
import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
import jp.ac.u_ryukyu.ie.cr.jungle.store.TreeContext;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.treeEditor.TreeEditor;
import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.TreeNode;
import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.TreeNodeChildren;
import jp.ac.u_ryukyu.ie.cr.jungle.store.index.ParentIndex;
import jp.ac.u_ryukyu.ie.cr.jungle.traverser.InterfaceTraverser;
import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Error;
import jp.ac.u_ryukyu.ie.cr.jungle.util.GetOldTreeError;

import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

public class PersistentJungleTree implements JungleTree {
    private final AtomicReference<TreeContext> repository;
    private final String uuid;
    private final String treeName;
    private final ChangeListWriter writer;
    private final TreeEditor editor;
    private int bufferSize;

    public PersistentJungleTree(String _treeName, TreeContext _tc, String _uuid, ChangeListWriter _writer, TreeEditor _editor, int _bufferSize) {
        treeName = _treeName;
        repository = new AtomicReference<TreeContext>(_tc);
        uuid = _uuid;
        writer = _writer;
        editor = _editor;
        bufferSize = _bufferSize;
    }

    @Override
    public JungleTreeEditor getJungleTreeEditor() {
        TreeContext tc = repository.get();
        PersistentTransactionManager txManager = new PersistentTransactionManager(treeName, writer, tc, repository, uuid, bufferSize);
        TreeNode root = tc.getRoot();
        ChangeList cl = tc.getChangeList();
        return new PersistentJungleTreeEditor(root, txManager, editor, cl.getLog());
    }

    @Override
    public TreeNode getRootNode() {
        TreeContext tc = repository.get();
        return tc.getRoot();
    }

    @Override
    public JungleTreeEditor getLocalJungleTreeEditor() {
        return getJungleTreeEditor();
    }

    @Override
    public long revision() {
        TreeContext tc = repository.get();
        return tc.revision();
    }

    @Override
    public Either<Error, JungleTree> getOldTree(long revision) {
        TreeContext tc = repository.get();

        for (; tc.revision() != revision; ) {
            tc = tc.prev();
            if (tc == null)
                return DefaultEither.newA(GetOldTreeError.OLD_TREE_NOT_FOUND);
        }


        String oldTreeUuid = uuid + revision;
        JungleTree oldTree = new DefaultJungleTree(tc, oldTreeUuid, writer, editor);
        return DefaultEither.newB(oldTree);
    }

    @Override
    public ParentIndex getParentIndex() {
        TreeContext tc = repository.get();
        return tc.getParentIndex();
    }

    @Override
    public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
        TreeContext tc = repository.get();
        return tc.getIndex();
    }

    @Override
    public InterfaceTraverser getTraverser(boolean useIndex) {
        TreeMap<String, TreeMap<String, List<TreeNode>>> index = getIndex();
        ParentIndex parentIndex = getParentIndex();
        return new InterfaceTraverser(getRootNode(), index, parentIndex, useIndex);
    }

    @Override
    public Either<Error, TreeNode> getNodeOfPath(NodePath path) {
        TreeNode node = repository.get().getRoot();
        for (int num : path) {
            if (num == -1)
                continue;
            Either<Error, TreeNode> either = node.getChildren().at(num);
            if (either.isA())
                return either;
            node = either.b();
        }
        return DefaultEither.newB(node);
    }

    @Override
    public void setBufferSize(int _bufferSize) {
        bufferSize = _bufferSize;
    }

    @Override
    public NodePath getNodePath(TreeNode node) {
        ParentIndex parentIndex = getParentIndex();
        DefaultNodePath path = new DefaultNodePath();
        Optional<TreeNode> parentOp = parentIndex.get(node);
        while(parentOp.isPresent()) {
            TreeNode parent = parentOp.get();
            TreeNodeChildren children = parent.getChildren();
            int num = 0;
            for (TreeNode child : children) {
                if (child == node)
                    break;
                num++;
            }
            path = path.add(num);
            node = parent;
            parentOp = parentIndex.get(node);
        }
        return path;
    }
}