view src/main/java/jp/ac/u_ryukyu/ie/cr/shoshi/jungle/traverser/InterfaceTraverser.java @ 132:ba5370090393

index commit Prototype
author one
date Sun, 19 Oct 2014 09:15:38 +0900
parents 1c3c3300716c
children f46a6e0e4594
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.traverser;

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

import fj.Ord;
import fj.data.List;
import fj.data.Option;
import fj.data.TreeMap;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTree;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTreeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.persistent.ChangeList;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.ChangeSet;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNode;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.AtomicReservableReference;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.DefaultChangeSet;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.DefaultTreeContext;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.IndexJungleTreeEditor;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction.TreeContext;
import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Pair;
import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.query.PathNodeIterator;
import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.query.Query;

public class InterfaceTraverser {

	//InterfaceTraverser traverser;
	TreeNode node;
	TreeMap<String, TreeMap<String, List<Pair<TreeNode, NodePath>>>> index;
	AtomicReservableReference<TreeContext>.Reservation reservation;

	public InterfaceTraverser(TreeNode _root, AtomicReservableReference<TreeContext>.Reservation reservation) {
		this.node = _root;
		this.index = TreeMap.empty(Ord.stringOrd);
		this.reservation = reservation;
	}

	public InterfaceTraverser(
			TreeNode _root,
			TreeMap<String, TreeMap<String, List<Pair<TreeNode, NodePath>>>> index,
			AtomicReservableReference<TreeContext>.Reservation reservation) {
		this.node = _root;
		this.index = index;
		this.reservation = reservation;
	}

	public void commitIndex(){
		TreeContext tc = reservation.get();
		ChangeSet cs = tc.getChangeSet();
		TreeNode root = cs.getRoot();
		ChangeSet prev = cs.prev();
		ChangeList cl = cs.getChangeList();
		String uuid = cs.uuid();
		String treeName = cs.getTreeName();
		long revision = cs.revision();
		ChangeSet newCs = new DefaultChangeSet(root, prev,cl, uuid, treeName, revision, index);
		TreeContext newTc = new DefaultTreeContext(root, newCs);
		reservation.set(newTc);
	}
	
	public TreeMap<String, TreeMap<String, List<Pair<TreeNode, NodePath>>>> getIndex() {
		return index;
	}

	public void setIndex(
			TreeMap<String, TreeMap<String, List<Pair<TreeNode, NodePath>>>> index) {
		this.index = index;
	}

	
	
/*	public InterfaceTraverser getTraverser(JungleTree tree) {
		return new InterfaceTraverser(tree.getRootNode(), tree.getIndex(),
				tree.getIndexTreeEditor());
	}*/

	public void set(TreeNode root) {
		this.node = root;
	}



	public Iterator<Pair<TreeNode, NodePath>> find(final Query query, String key, String searchValue) {
		
		if (index.get(key).isSome()) {

			TreeMap<String, List<Pair<TreeNode, NodePath>>> innerIndex = this.index.get(key).some();
			Option<List<Pair<TreeNode, NodePath>>> opList = innerIndex.get(searchValue);

			if (opList.isNone())
				return null;//空のIteratorを返す

			final List<Pair<TreeNode, NodePath>> list = opList.some();
			return list.iterator();

		} else {
			
			final PathNodeIterator itNode = new PathNodeIterator(node);
			return new Iterator<Pair<TreeNode, NodePath>>() {

				private Pair<TreeNode, NodePath> matchPair = nextmatch(itNode);

				private Pair<TreeNode, NodePath> nextmatch(
						PathNodeIterator itNode) {

					for (; itNode.hasNext();) {
						Pair<TreeNode, NodePath> pathNode = itNode.next();
						String value = pathNode.left().getAttributes().getString(key);
						Option<TreeMap<String, List<Pair<TreeNode, NodePath>>>> innerIndexOp = index.get(key);
						System.out.println("value = "+ value);

						if (value != null) {
							if (innerIndexOp.isNone()) {

								TreeMap<String, List<Pair<TreeNode, NodePath>>> innerIndex = TreeMap.empty(Ord.stringOrd);
								List<Pair<TreeNode, NodePath>> list = List.nil();
								list = list.cons(pathNode);
								innerIndex = innerIndex.set(value, list);
								index = index.set(key, innerIndex);

							} else {

								TreeMap<String, List<Pair<TreeNode, NodePath>>> innerIndex = innerIndexOp.some();
								Option<List<Pair<TreeNode, NodePath>>> opList = innerIndex.get(value);

								if (opList.isNone()) {

									List<Pair<TreeNode, NodePath>> list = List.nil();
									list = list.cons(pathNode);
									innerIndex = innerIndex.set(value, list);

								} else {

									List<Pair<TreeNode, NodePath>> list = opList.some();
									list = list.cons(pathNode);
									innerIndex = innerIndex.set(value, list);

								}
								index = index.set(key, innerIndex);

							}
						}

						if (query.condition(pathNode.left()))
							return pathNode;
					}
					return null;
				}

				@Override
				public boolean hasNext() {
					if (matchPair == null) {
//						index = itNode.getIndex();
						return false;
					}
					return true;
				}

				@Override
				public Pair<TreeNode, NodePath> next() {
					Pair<TreeNode, NodePath> currentPair = matchPair;
					matchPair = nextmatch(itNode);
					return currentPair;
				}

				@Override
				public void remove() {
					// TODO Auto-generated method stub

				}

			};
		}
	}
}