# 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("
\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 {
+ }
+
+}