# HG changeset patch # User tatsuki # Date 1466971579 -32400 # Node ID 3c188a5b69ef40e8d61213c7da2c093ef73b8d4a # Parent 64a72a7a0491f34c1b15538271e6d9dd8945c757 add network bbs diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/BoardRenewTime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/BoardRenewTime.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,8 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network; + +public interface BoardRenewTime { + + public String getboardName(); + public Long getRenewTime(); + +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/BulletinBoardJungleManager.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/BulletinBoardJungleManager.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,109 @@ +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.JungleTree; +import jp.ac.u_ryukyu.ie.cr.jungle.JungleTreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.DefaultNodePath; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.DefaultTreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.TreeNode; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser; +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.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 { + private static BulletinBoardJungleManager instance = new BulletinBoardJungleManager(); + private Jungle jungle; + private static AtomicInteger requestCounter = new AtomicInteger(0); + + private BulletinBoardJungleManager() { + jungle = new DefaultJungle(null,"default",new DefaultTreeEditor(new DefaultTraverser())); + } + + public static int requestGetAndIncrement() { + return requestCounter.getAndIncrement(); + } + + public static int requestIncrementAndGet() { + return requestCounter.incrementAndGet(); + } + + public static BulletinBoardJungleManager getInstantce() { + return instance; + } + + public static void setJungle(Jungle _j) { + instance.jungle = _j; + } + public static AtomicInteger getRequestCounter() { + return requestCounter; + } + + public static Jungle getJungle() { + return instance.jungle; + } + + public static JungleTree createNewTree(String name) { + return instance.jungle.createNewTree(name); + } + + public static Either update(NetworkTreeOperationLog netLog) { + String treeName = netLog.getTreeName(); + Jungle jungle = jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.BulletinBoardJungleManager.getJungle(); + if (jungle.getTreeByName(treeName) == null) { + if(null == jungle.createNewTree(treeName)){ + throw new IllegalStateException(); + } + } + Either 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.getLocalTreeEditor(); + /* + * 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 static 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; + } +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/DistributeApp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/DistributeApp.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,20 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network; + +import alice.topology.node.TopologyNode; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.codesegment.StartBBSCodeSegment; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.remote.RemoteConfig; + +public class DistributeApp { + public static void main(String[] args) throws Exception { + RemoteConfig conf = new RemoteConfig(args); + System.out.println("test"); + if (conf.getManagerHostName() == null) { + // String localHostName ="localhost"; + // HostMessage host = new HostMessage(localHostName, conf.localPort); + StartBBSCodeSegment cs1 = new StartBBSCodeSegment(args, conf.bbsPort); + cs1.ods.put("host", "node0"); + } else { + new TopologyNode(conf, new StartBBSCodeSegment(args, conf.bbsPort)); + } + } +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/NetworkBulletinBoard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/NetworkBulletinBoard.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,16 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network; + + +import jp.ac.u_ryukyu.ie.cr.jungle.bbs.BulletinBoard; + +public interface NetworkBulletinBoard extends BulletinBoard { + public void init(); + public int getRequestNum(); + public long getRenewTime(String boardName); + public void createFolder(String boardName, String author, String msg, String key, String _nodeNum); + public void createAttribute(String boardName, String uuid, String author, String msg, String key); + public void editAttribute(String boardName, String path, String id, String message); + public void deleteAttribute(String _board, String _path, String id); + public void deleteNode(String _board, String _path, String id); + +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/NetworkJungleBulletinBoard.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/NetworkJungleBulletinBoard.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,691 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network; + + +import jp.ac.u_ryukyu.ie.cr.jungle.Jungle; +import jp.ac.u_ryukyu.ie.cr.jungle.JungleTree; +import jp.ac.u_ryukyu.ie.cr.jungle.JungleTreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.bbs.BoardMessage; +import jp.ac.u_ryukyu.ie.cr.jungle.bbs.GetAttributeImp; +import jp.ac.u_ryukyu.ie.cr.jungle.bbs.IterableConverter; +import jp.ac.u_ryukyu.ie.cr.jungle.core.Children; +import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeList; +import jp.ac.u_ryukyu.ie.cr.jungle.persistent.ChangeListReader; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.DefaultNodePath; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.DefaultTreeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.TreeNode; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.logger.DefaultOperationLog; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.logger.LoggingNode; +import jp.ac.u_ryukyu.ie.cr.jungle.store.impl.logger.OperationLog; +import jp.ac.u_ryukyu.ie.cr.jungle.store.trasnformer.NodeEditor; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultEvaluator; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.DefaultTraverser; +import jp.ac.u_ryukyu.ie.cr.jungle.traverser.Traversal; +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.jungleNetwork.bbs.BulletinBoardJungleManager; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.NetworkBulletinBoard; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.core.NetworkDefaultJungle; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent.AliceJournal; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent.NetworkJournal; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.persistent.PersistentJournal; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.transaction.JungleUpdater; +import junit.framework.Assert; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicInteger; + +public class NetworkJungleBulletinBoard implements NetworkBulletinBoard { + protected final Jungle jungle; + private final NetworkJournal journal; + private final String LOG_DIR; + private Boolean persistentFlag; + private AtomicInteger requestCounter; + private long renewTime; + + private NetworkJungleBulletinBoard(String _uuid, NetworkJournal _journal) { + journal = _journal; + jungle = new NetworkDefaultJungle(journal, _uuid, new DefaultTreeEditor(new DefaultTraverser())); + BulletinBoardJungleManager.setJungle(jungle); + persistentFlag = false; + requestCounter = BulletinBoardJungleManager.getRequestCounter(); + LOG_DIR = "./log"; + renewTime = 0; + } + + public NetworkJungleBulletinBoard(String _uuid) { + this(_uuid, new AliceJournal()); + jungle.createNewTree("boards"); + } + + public static NetworkBulletinBoard NewPersistentJungle(String _uuid) { + NetworkJungleBulletinBoard board = new NetworkJungleBulletinBoard(_uuid, new PersistentJournal()); + board.persistentFlag = true; + return board; + } + + public void init() { + if (!persistentFlag) { + return; + } + checkAndCreateLogDirectory(); + try { + commitLogRecover(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void checkAndCreateLogDirectory() { + File logFile = new File(LOG_DIR); + if (!logFile.exists()) { + logFile.mkdir(); + return; + } + if (logFile.isFile()) { + logFile.delete(); + logFile.mkdir(); + } + } + + public void commitLogRecover() throws IOException { + File[] logFiles = new File(LOG_DIR).listFiles(); + for (File logFile : logFiles) { + commitLogRecover(logFile); + logFile.delete(); + } + if (jungle.getTreeByName("boards") == null) { + jungle.createNewTree("boards"); + } + } + + private void commitLogRecover(File logFile) throws IOException { + journal.setInputFile(logFile); + ChangeListReader reader = journal.getReader(); + if (reader == null) + return; + for (ChangeList chList : reader) { + String treeName = chList.getTreeName(); + JungleTree tree = jungle.getTreeByName(treeName); + if (tree == null) { + tree = jungle.createNewTree(treeName); + } + JungleTreeEditor editor = tree.getLocalTreeEditor(); + Either either = JungleUpdater.edit(editor, chList); + editor = either.b(); + if (either.isA()) { + throw new IOException("Failed commit log recovery"); + } + editor.success(); + } + } + + public Iterable getBoards() { + JungleTree tree = jungle.getTreeByName("boards"); + TreeNode node = tree.getRootNode(); + Children chs = node.getChildren(); + + IterableConverter.Converter converter = new IterableConverter.Converter() { + public String conv(TreeNode _b) { + ByteBuffer e = _b.getAttributes().get("name"); + System.out.println(new String(e.array())); + return new String(e.array()); + } + }; + + return new IterableConverter(chs, converter); + } + + public long getRenewTime(String _boardName) { + return renewTime; + } + + public void createBoards(final String _name, final String _author, final String _initMessage, final String _editKey) { + requestCounter.incrementAndGet(); + if (null == jungle.createNewTree(_name)) { + throw new IllegalStateException(); + } + + JungleTree tree = jungle.getTreeByName("boards"); + JungleTreeEditor editor = tree.getTreeEditor(); + DefaultNodePath root = new DefaultNodePath(); + Either either = editor.addNewChildAt(root, 0); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + + either = editor.putAttribute(root.add(0), "name", ByteBuffer.wrap(_name.getBytes())); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + final long timestamp = System.currentTimeMillis(); + ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + either = editor.putAttribute(root.add(0), "timestamp", tBuffer); + if (either.isA()) { + throw new IllegalStateException(); + } + either = either.b().success(); + if (either.isA()) { + throw new IllegalStateException(); + } + + tree = jungle.getTreeByName(_name); + editor = tree.getTreeEditor(); + either = editor.addNewChildAt(root, 0); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + + NodeEditor e = new NodeEditor() { + ByteBuffer tBuffer2 = ByteBuffer.allocate(16); + + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b(); + logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_initMessage.getBytes())).b(); + logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b(); + tBuffer2.putLong(timestamp); + logNode = logNode.getAttributes().put("timestamp", tBuffer2).b(); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + + either = editor.edit(root.add(0), e); + if (either.isA()) { + throw new IllegalStateException(); + } + either.b().success(); + + } + + public void createFolder(final String _board, final String _author, final String _message, final String _editKey, + String _path) { + JungleTree tree = jungle.getTreeByName(_board); + if (tree == null) { + throw new IllegalStateException(); + } + + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + + requestCounter.incrementAndGet(); + Either either; + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + + do { + TreeNode node = tree.getRootNode(); + DefaultTraverser traverser = new DefaultTraverser(); + DefaultEvaluator evaluator = new DefaultEvaluator(path); + Either ret = traverser.traverse(node, evaluator); + if (ret.isA()) { + Assert.fail(); + } + + Traversal traversal = ret.b(); + TreeNode target = traversal.destination(); + int size = target.getChildren().size(); + JungleTreeEditor editor = tree.getTreeEditor(); + either = editor.addNewChildAt(path, size); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + + NodeEditor e = new NodeEditor() { + + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b(); + logNode = logNode.getAttributes().put("timestamp", tBuffer).b(); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + + }; + path = path.add(size); + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + + } + + public void createBoardMessage(final String _board, final String _author, final String _message, final String _editKey) { + requestCounter.incrementAndGet(); + JungleTree tree = jungle.getTreeByName(_board); + if (tree == null) { + throw new IllegalStateException(); + } + + Either either; + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + do { + + TreeNode node = tree.getRootNode(); + int size = node.getChildren().size(); + DefaultNodePath path = new DefaultNodePath(); + + JungleTreeEditor editor = tree.getTreeEditor(); + either = editor.addNewChildAt(path, size); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + + NodeEditor e = new NodeEditor() { + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b(); + logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b(); + logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b(); + logNode = logNode.getAttributes().put("timestamp", tBuffer).b(); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + path = path.add(size); + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + + } + + public void editMessage(String _board, String _path, final String _author, final String _message, + final String _editKey) { + requestCounter.incrementAndGet(); + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + JungleTree tree = jungle.getTreeByName(_board); + Either either = null; + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + do { + + JungleTreeEditor editor = tree.getTreeEditor(); + NodeEditor e = new NodeEditor() { + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + System.out.println(new String(node.getAttributes().get("mes").array())); + logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b(); + logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b(); + logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b(); + logNode = logNode.getAttributes().put("timestamp", tBuffer).b(); + System.out.println(new String(node.getAttributes().get("mes").array())); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + renewTime = timestamp; + } + + public void createAttribute(String _board, String _path, final String _author, final String _message, + final String _editKey) { + requestCounter.incrementAndGet(); + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + JungleTree tree = jungle.getTreeByName(_board); + Either either = null; + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + + do { + JungleTreeEditor editor = tree.getTreeEditor(); + NodeEditor e = new NodeEditor() { + String str; + + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + str = "0"; + int count = 0; + for (; logNode.getAttributes().get("mes" + String.valueOf(count)) != null; count++) { + } + str = String.valueOf(count); + logNode = logNode.getAttributes().put("mes" + str, ByteBuffer.wrap(_message.getBytes())).b(); + logNode = logNode.getAttributes().put("timestamp" + str, tBuffer).b(); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + } + + public void editAttribute(String _bname, String _path, final String id, final String _message) { + requestCounter.incrementAndGet(); + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + JungleTree tree = jungle.getTreeByName(_bname); + Either either = null; + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + + do { + JungleTreeEditor editor = tree.getTreeEditor(); + NodeEditor e = new NodeEditor() { + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + logNode = logNode.getAttributes().put("mes" + id, ByteBuffer.wrap(_message.getBytes())).b(); + logNode = logNode.getAttributes().put("timestamp" + id, tBuffer).b(); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + } + + public void deleteNode(String _board, String _path, String _id) { + requestCounter.incrementAndGet(); + int id = Integer.parseInt(_id); + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + JungleTree tree = jungle.getTreeByName(_board); + Either either = null; + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + + do { + JungleTreeEditor editor = tree.getTreeEditor(); + + either = editor.deleteChildAt(path, id); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + + } + + public void deleteAttribute(String _board, String _path, final String id) { + requestCounter.incrementAndGet(); + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + JungleTree tree = jungle.getTreeByName(_board); + Either either = null; + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + + do { + JungleTreeEditor editor = tree.getTreeEditor(); + NodeEditor e = new NodeEditor() { + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + logNode = logNode.getAttributes().delete("mes" + id).b(); + logNode = logNode.getAttributes().delete("timestamp" + id).b(); + int count = Integer.parseInt(id); + for (; logNode.getAttributes().get("mes" + String.valueOf(count + 1)) != null; ) { + logNode = logNode.getAttributes() + .put("mes" + count, node.getAttributes().get("mes" + String.valueOf(count + 1))).b(); + logNode = logNode.getAttributes().put("timestamp" + count, tBuffer).b(); + count++; + } + if (count != Integer.parseInt(id)) { + logNode = logNode.getAttributes().delete("timestamp" + count).b(); + logNode = logNode.getAttributes().delete("mes" + count).b(); + } + + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + } + + public void editMatrixMessage(String _board, String _uuid, final String _author, final String _message, + final String _editKey) { + requestCounter.incrementAndGet(); + final long timestamp = System.currentTimeMillis(); + final ByteBuffer tBuffer = ByteBuffer.allocate(16); + tBuffer.putLong(timestamp); + JungleTree tree = jungle.getTreeByName(_board); + Either either = null; + do { + DefaultNodePath path = new DefaultNodePath(); + path = path.add(Integer.parseInt(_uuid)); + + JungleTreeEditor editor = tree.getTreeEditor(); + NodeEditor e = new NodeEditor() { + public Either edit(TreeNode node) { + LoggingNode logNode = wrap(node, new DefaultOperationLog()); + logNode = logNode.getAttributes().put("author", ByteBuffer.wrap(_author.getBytes())).b(); + logNode = logNode.getAttributes().put("mes", ByteBuffer.wrap(_message.getBytes())).b(); + logNode = logNode.getAttributes().put("key", ByteBuffer.wrap(_editKey.getBytes())).b(); + logNode = logNode.getAttributes().put("timestamp", tBuffer).b(); + return DefaultEither.newB(logNode); + } + + @Override + public LoggingNode wrap(TreeNode node, OperationLog op) { + return new LoggingNode(node, op); + } + }; + either = editor.edit(path, e); + if (either.isA()) { + throw new IllegalStateException(); + } + editor = either.b(); + either = editor.success(); + } while (either.isA()); + renewTime = timestamp; + } + + public Iterable getFolder(String _boardName, String _nodeNum) { + DefaultNodePath path = new DefaultNodePath(); + System.out.println(_nodeNum.substring(0, 1)); + String[] nums = _nodeNum.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + JungleTree tree = jungle.getTreeByName(_boardName); + TreeNode node = tree.getRootNode(); + requestCounter.incrementAndGet(); + + DefaultTraverser traverser = new DefaultTraverser(); + DefaultEvaluator evaluator = new DefaultEvaluator(path); + Either ret = traverser.traverse(node, evaluator); + if (ret.isA()) { + Assert.fail(); + } + + Traversal traversal = ret.b(); + TreeNode target = traversal.destination(); + Children chs = target.getChildren(); + + final AtomicInteger counter = new AtomicInteger(0); + IterableConverter.Converter converter = new IterableConverter.Converter() { + public BoardMessage conv(TreeNode _b) { + String uuid = Integer.toString(counter.get()); + String message = new String(_b.getAttributes().get("mes").array()); + counter.incrementAndGet(); + return new BoardMessageImpl(null, message, uuid); + } + }; + return new IterableConverter(chs, converter); + } + + public boolean compare(TreeNode compareNode, String compareAttribute) { + String labName = compareNode.getAttributes().getString("mes"); + if (labName.equals(compareAttribute)) + return true; + + for (int loopCount = 0; compareNode.getAttributes().getString("mes" + loopCount) != null; loopCount++) { + labName = compareNode.getAttributes().getString("mes" + loopCount); + if (labName.equals(compareAttribute)) + return true; + } + + return false; + } + + public int getRequestNum() { + return requestCounter.get(); + } + + private static class BoardMessageImpl implements BoardMessage { + private final String author; + private final String message; + private final String uuid; + + public BoardMessageImpl(String _author, String _message, String _uuid) { + author = _author; + message = _message; + uuid = _uuid; + } + + public String getAuthor() { + return author; + } + + public String getMessage() { + return message; + } + + public String getUUID() { + return uuid; + } + + } + + public String sanitize(String str) { + if (str == null) { + return str; + } + str = str.replaceAll("&", "&"); + str = str.replaceAll("<", "<"); + str = str.replaceAll(">", ">"); + str = str.replaceAll("\"", """); + str = str.replaceAll("'", "'"); + return str; + } + + @Override + public GetAttributeImp getAttribute(String _bname, String _path, String revisionStr) { + DefaultNodePath path = new DefaultNodePath(); + String[] nums = _path.split(","); + for (String num : nums) { + if (!num.equals("-1")) + path = path.add(Integer.parseInt(num)); + } + + JungleTree tree = jungle.getTreeByName(_bname); + TreeNode node; + if (revisionStr.equals("-1")) { + node = tree.getRootNode(); + } else { + Long revision = Long.parseLong(revisionStr); + JungleTree oldTree = tree.getOldTree(revision).b(); + node = oldTree.getRootNode(); + } + + DefaultTraverser traverser = new DefaultTraverser(); + DefaultEvaluator evaluator = new DefaultEvaluator(path); + Either ret = traverser.traverse(node, evaluator); + if (ret.isA()) { + Assert.fail(); + } + + Traversal traversal = ret.b(); + TreeNode target = traversal.destination(); + return new GetAttributeImp(target); + } +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/RequestNumCheckServlet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/RequestNumCheckServlet.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,36 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network; + +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.NetworkBulletinBoard; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; + + +public class RequestNumCheckServlet extends HttpServlet +{ + private final NetworkBulletinBoard bbs; + private static final long serialVersionUID = 1L; + + public RequestNumCheckServlet(NetworkBulletinBoard _bbs) + { + bbs = _bbs; + } + + public void doGet(HttpServletRequest _req,HttpServletResponse _res) + { + int num = bbs.getRequestNum(); + + try{ + PrintWriter pw = _res.getWriter(); + pw.write(Integer.toString(num)); + pw.flush(); + }catch(Exception _e){ + _res.setStatus(500); + } + + + } + +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/ShowMessageWithTimeStampServlet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/ShowMessageWithTimeStampServlet.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,65 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network; + +import jp.ac.u_ryukyu.ie.cr.jungle.bbs.GetAttributeImp; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.NetworkBulletinBoard; +import org.eclipse.jetty.util.thread.ThreadPool; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; +import java.util.Iterator; + +public class ShowMessageWithTimeStampServlet extends HttpServlet { + /** + * + */ + private static final long serialVersionUID = 1L; + private final jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.NetworkBulletinBoard bbs; + private final String createBoardMessagePath; + + private static final String PARAM_BOARD_NAME = "bname"; + private final String editMessagePath; + + public ShowMessageWithTimeStampServlet(NetworkBulletinBoard _bbs, + String _createBoardMessagePath, String _editMessagePath, ThreadPool thp) { + bbs = _bbs; + createBoardMessagePath = _createBoardMessagePath; + editMessagePath = _editMessagePath; + } + + public void doGet(HttpServletRequest _req, HttpServletResponse _res) { + final String bname = (_req.getParameter(PARAM_BOARD_NAME)); + try { + _res.setCharacterEncoding("UTF-8"); + printBoard(bname, _res.getWriter()); + } catch (Exception _e) { + _res.setStatus(500); + } + } + + private void printBoard(String _bname, PrintWriter _pw) throws Exception { + _pw.write("\n"); + _pw.write("

" + bbs.sanitize(_bname) + "

\n"); + _pw.write("

Latest renew time : " + bbs.getRenewTime(_bname) + + "

\n"); + ; + + _pw.write("
Author : EditKey :

\n"); + _pw.write("

Message

\n"); + _pw.write("

\n"); + + GetAttributeImp attribute = bbs.getAttribute(_bname, "[-1]", "0"); + Iterator keys = attribute.getKeys(); + + while (keys.hasNext()) { + String key = keys.next(); + String mesage = attribute.getMessage(key); + _pw.write("

" + key + " = " + mesage + "

\n"); + } + _pw.write("

edit" + "

"); + _pw.write(""); + _pw.flush(); + } +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/codesegment/LogPutCodeSegment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/codesegment/LogPutCodeSegment.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,20 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network.codesegment; + +import alice.codesegment.CodeSegment; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.operations.NetworkTreeOperationLog; + + +public class LogPutCodeSegment extends CodeSegment{ + + NetworkTreeOperationLog log; + + public LogPutCodeSegment(NetworkTreeOperationLog _log) { + log = _log; + } + + @Override + public void run() { + ods.put("log", log); + } + +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/codesegment/LogUpdateCodeSegment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/codesegment/LogUpdateCodeSegment.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,48 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network.codesegment; + +import alice.codesegment.CodeSegment; +import alice.datasegment.CommandType; +import alice.datasegment.Receiver; +import jp.ac.u_ryukyu.ie.cr.jungle.JungleTreeEditor; +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.jungleNetwork.bbs.BulletinBoardJungleManager; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.operations.NetworkTreeOperationLog; + +import java.util.List; + +public class LogUpdateCodeSegment extends CodeSegment { + + Receiver log = ids.create(CommandType.TAKE); + Receiver clist = ids.create(CommandType.PEEK); + + public LogUpdateCodeSegment() { + log.setKey("log"); + clist.setKey("_CLIST");; + } + + public LogUpdateCodeSegment(int index) { + log.setKey("log", index); + clist.setKey("_CLIST");; + } + + public void run() { + int index = log.index; + new jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.codesegment.LogUpdateCodeSegment(); + NetworkTreeOperationLog netLog = log.asClass(NetworkTreeOperationLog.class); + @SuppressWarnings("unchecked") + List list = clist.asClass(List.class); + for (String node : list) { + if (!node.equals(log.from)) { + ods.put(node, log.key, log.getVal()); + } + } + if (!log.from.equals("local")) { + Either either = BulletinBoardJungleManager.update(netLog); + if(either.isA()) { + new jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.codesegment.LogUpdateCodeSegment(index); + throw new IllegalStateException(); + } + } + } +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/codesegment/StartBBSCodeSegment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/codesegment/StartBBSCodeSegment.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,101 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network.codesegment; + +import alice.codesegment.CodeSegment; +import alice.datasegment.CommandType; +import alice.datasegment.Receiver; +import jp.ac.u_ryukyu.ie.cr.jungle.bbs.*; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.NetworkBulletinBoard; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.NetworkJungleBulletinBoard; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.RequestNumCheckServlet; +import jp.ac.u_ryukyu.ie.cr.jungleNetwork.bbs.codesegment.LogUpdateCodeSegment; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.eclipse.jetty.util.thread.ThreadPool; + +import javax.servlet.Servlet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class StartBBSCodeSegment extends CodeSegment { + + int bbsPort = 8080; + Receiver host = ids.create(CommandType.PEEK); + private Pattern pattern = Pattern.compile("^(node|cli)([0-9]+)$"); + private String[] args; + boolean persistentFlag = false; + + public StartBBSCodeSegment(String[] _args, int p) { + args = _args; + bbsPort = p; + host.setKey("host"); + } + + public StartBBSCodeSegment() { + args = null; + host.setKey("host"); + } + + @Override + public void run() { + String name = host.asString(); + Matcher matcher = pattern.matcher(name); + matcher.find(); + // String type = matcher.group(1); + for(String arg: args) { + if(arg.equals("-persistent")){ + persistentFlag = true; + } + } + NetworkBulletinBoard cassaBBS = null; + if(persistentFlag) { + System.out.println("log loading..."); + cassaBBS = NetworkJungleBulletinBoard.NewPersistentJungle(name); + cassaBBS.init(); + } else { + cassaBBS = new NetworkJungleBulletinBoard(name); + cassaBBS.init(); + } + + System.out.println("StartBBSCodeSegment"); + System.out.println("name : "+ name); + /* Jetty registration */ + String createBoardMessagePath = "/createBoardMessage"; + String createBoardPath = "/createBoard"; + String editMessagePath = "/editMessage"; + String showBoardMessagePath = "/showBoardMessage"; + + + Server serv = new Server(bbsPort); + ThreadPool thp = serv.getThreadPool(); + Servlet createBoardMessage = new CreateBoardMessageServlet(cassaBBS); + Servlet createBoard = new CreateBoardServlet(cassaBBS); + Servlet editBoardMessage = new EditMessageServlet(cassaBBS); + Servlet index = new ShowBoardsServlet(cassaBBS,createBoardPath,showBoardMessagePath); + Servlet board = new ShowBoardMessageServlet(cassaBBS,createBoardMessagePath,editMessagePath); + //Servlet board = new ShowMessageWithTimeStampServlet(cassaBBS,createBoardMessagePath,thp); + + ServletHandler context = new ServletHandler(); + context.addServletWithMapping(new ServletHolder(createBoardMessage),createBoardMessagePath); + context.addServletWithMapping(new ServletHolder(createBoard),createBoardPath); + context.addServletWithMapping(new ServletHolder(editBoardMessage),editMessagePath); + context.addServletWithMapping(new ServletHolder(index),"/"); + context.addServletWithMapping(new ServletHolder(board),showBoardMessagePath); + /* + * For write benchmark + */ + String editMessageUseGetPath = "/editMessageUseGet"; + Servlet editMessageUseGet = new EditMessageUseGetServlet(cassaBBS); + context.addServletWithMapping(new ServletHolder(editMessageUseGet), editMessageUseGetPath); + String requestNumCheckPath = "/requestNum"; + Servlet requestNumCheckServlet = new RequestNumCheckServlet(cassaBBS); + context.addServletWithMapping(new ServletHolder(requestNumCheckServlet), requestNumCheckPath); + + serv.setHandler(context); + try { + serv.start(); + } catch (Exception e) { } + new LogUpdateCodeSegment(); + } + +} diff -r 64a72a7a0491 -r 3c188a5b69ef src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/io/NullOutputStream.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/bbs/network/io/NullOutputStream.java Mon Jun 27 05:06:19 2016 +0900 @@ -0,0 +1,15 @@ +package jp.ac.u_ryukyu.ie.cr.bbs.network.io; + +import java.io.IOException; +import java.io.OutputStream; + +public class NullOutputStream extends OutputStream { + + public NullOutputStream() { + } + + @Override + public void write(int arg0) throws IOException { + } + +}