view src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/BulletinBoardJungleManager.java @ 20:7164db5bc76f

fix BulltinBoardJungleamanager singleton
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 28 Aug 2017 11:14:19 +0900
parents 6e91ad317eb0
children
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.bbs.network;


import jp.ac.u_ryukyu.ie.cr.jungle.DefaultJungle;
import jp.ac.u_ryukyu.ie.cr.jungle.Jungle;
import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.jungle.util.jungleError.Error;
import jp.ac.u_ryukyu.ie.cr.jungleNetwork.codesegment.JungleDistributedUpdator;
import jp.ac.u_ryukyu.ie.cr.jungleNetwork.operations.NetworkTreeOperationLog;
import jp.ac.u_ryukyu.ie.cr.jungleNetwork.transaction.JungleUpdater;

import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;

public class BulletinBoardJungleManager implements JungleDistributedUpdator {
	private Jungle jungle;
	private AtomicInteger requestCounter = new AtomicInteger(0);

	BulletinBoardJungleManager(Jungle jungle) {
		this.jungle = jungle;
	}
	
	public int requestGetAndIncrement() {
		return requestCounter.getAndIncrement();
	}
	
	public int requestIncrementAndGet() {
		return requestCounter.incrementAndGet();
	}
	
	public void setJungle(Jungle _j) {
		jungle = _j;
	}
	public AtomicInteger getRequestCounter() {
		return requestCounter;
	}
	
	public Jungle getJungle() {
		return jungle;
	}
	
	public JungleTree createNewTree(String name) {
		return jungle.createNewTree(name);
	}

	@Override
	public Either<Error, JungleTreeEditor> update(NetworkTreeOperationLog netLog) {
		String treeName = netLog.getTreeName();
		Jungle jungle = getJungle();
		if (jungle.getTreeByName(treeName) == null) {
			if(null == jungle.createNewTree(treeName)){
				throw new IllegalStateException();
			}
		}
		Either<Error, JungleTreeEditor> either = null;
		JungleTree tree = jungle.getTreeByName(treeName);
		
		long timestamp = System.currentTimeMillis();
		ByteBuffer tBuffer = ByteBuffer.allocate(16);
		DefaultNodePath root = new DefaultNodePath();
		tBuffer.putLong(timestamp);
		do {
			JungleTreeEditor editor = tree.getJungleTreeEditor();
			/* 
			 * Merge. 
			 */
			int pos = calculatePosition(tree.getRootNode(), netLog.getTimeStamp());
			either = JungleUpdater.edit(editor, netLog, pos);
			if(either.isA()) {
				throw new IllegalStateException();
			}
			editor = either.b();
			either = editor.putAttribute(root, "renewtime", tBuffer);
			if(either.isA()) {
				throw new IllegalStateException();
			}
			editor = either.b();
			either = editor.success();
		}while(either.isA());
		requestIncrementAndGet();
		return either;
	}
	
	private int calculatePosition(TreeNode node, long newNodeTimeStamp) {
		int count = 0;
		long childTimeStamp = 0;
		for(TreeNode n : node.getChildren()) {
			ByteBuffer timestamp = n.getAttributes().get("timestamp");
			if(timestamp == null) {
				return count;
			}
			childTimeStamp = timestamp.getLong(0);
			if (newNodeTimeStamp < childTimeStamp) {
				break;
			}
			count++;
		}
		return count;
	}
}