118
|
1 package jp.ac.u_ryukyu.ie.cr.shoshi.jungle.transaction;
|
|
2
|
|
3 import java.nio.ByteBuffer;
|
149
|
4 import java.util.Iterator;
|
118
|
5
|
149
|
6 import fj.P2;
|
118
|
7 import fj.data.List;
|
|
8 import fj.data.TreeMap;
|
|
9 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.JungleTreeEditor;
|
|
10 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.NodePath;
|
145
|
11 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.IndexTreeEditor;
|
118
|
12 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNode;
|
149
|
13 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.TreeNodeChildren;
|
118
|
14 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.DefaultTreeOperationLog;
|
|
15 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.LoggingNode;
|
|
16 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.OperationLog;
|
|
17 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.impl.logger.TreeOperationLog;
|
|
18 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.DefaultTreeOperation;
|
|
19 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.NodeOperation;
|
|
20 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.operations.TreeOperation;
|
|
21 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.AppendChildAt;
|
|
22 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.DeleteAttribute;
|
|
23 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.DeleteChildAt;
|
|
24 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.NodeEditor;
|
|
25 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.store.trasnformer.PutAttribute;
|
|
26 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.DefaultEither;
|
|
27 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Either;
|
|
28 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Error;
|
|
29 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.IterableConverter;
|
149
|
30 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.Pair;
|
|
31 import jp.ac.u_ryukyu.ie.cr.shoshi.jungle.util.TreeMapOrd;
|
128
|
32 import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.DefaultIndexEditor;
|
|
33 import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.DeleteChildIndexEditor;
|
118
|
34 import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.IndexEditor;
|
149
|
35 import jp.ac.u_ryukyu.ie.cr.tatsuki.jungle.store.index.ParentIndex;
|
118
|
36
|
145
|
37 public class IndexJungleTreeEditor implements JungleTreeEditor {
|
|
38 private final TransactionManager txManager;
|
|
39 private final TreeNode root;
|
149
|
40 private final TreeNode oldRoot;
|
145
|
41 private final IndexTreeEditor editor;
|
|
42 private final TreeOperationLog log;
|
149
|
43 private final TreeOperationLog tmpLog;
|
146
|
44 private TreeMap<String, TreeMap<String, List<TreeNode>>> index;
|
149
|
45 private ParentIndex parentIndex;
|
145
|
46
|
146
|
47 public TreeMap<String, TreeMap<String, List<TreeNode>>> getIndex() {
|
145
|
48 return index;
|
|
49 }
|
|
50
|
149
|
51 public IndexJungleTreeEditor(TreeNode _root, TreeNode oldRoot, TransactionManager _txManager,
|
|
52 IndexTreeEditor treeEditor, TreeMap<String, TreeMap<String, List<TreeNode>>> index,
|
|
53 ParentIndex parentIndex) {
|
|
54 this(_root, oldRoot, _txManager, treeEditor, new DefaultTreeOperationLog(), new DefaultTreeOperationLog(), index, parentIndex);
|
145
|
55 }
|
118
|
56
|
149
|
57 public IndexJungleTreeEditor(TreeNode _root, TreeNode oldRoot, TransactionManager _txManager,
|
|
58 IndexTreeEditor treeEditor, TreeOperationLog log, TreeMap<String, TreeMap<String, List<TreeNode>>> index,
|
|
59 ParentIndex parentIndex) {
|
|
60 this(_root, oldRoot, _txManager, treeEditor, log, new DefaultTreeOperationLog(), index, parentIndex);
|
|
61 }
|
|
62
|
|
63 public IndexJungleTreeEditor(TreeNode newNode, TreeNode oldRoot, TransactionManager _txManager,
|
|
64 IndexTreeEditor _editor, TreeOperationLog _log, TreeOperationLog tmpLog,
|
|
65 TreeMap<String, TreeMap<String, List<TreeNode>>> index, ParentIndex parentIndex) {
|
145
|
66 this.root = newNode;
|
149
|
67 this.oldRoot = oldRoot;
|
145
|
68 this.txManager = _txManager;
|
|
69 this.editor = _editor;
|
|
70 this.log = _log;
|
|
71 this.index = index;
|
|
72 this.parentIndex = parentIndex;
|
149
|
73 this.tmpLog = tmpLog;
|
145
|
74 }
|
118
|
75
|
145
|
76 public Either<Error, IndexJungleTreeEditor> _edit(final NodePath _path, NodeEditor _e, IndexEditor indexEditor) {
|
149
|
77 Either<Error, LoggingNode> either = editor.edit(root, _path, _e);
|
145
|
78 if (either.isA()) {
|
|
79 return DefaultEither.newA(either.a());
|
|
80 }
|
|
81
|
149
|
82 LoggingNode newLogging = either.b();
|
145
|
83 OperationLog newLog = newLogging.getOperationLog();
|
|
84 TreeNode newNode = newLogging.getWrap();
|
|
85
|
|
86 IterableConverter.Converter<TreeOperation, NodeOperation> converter = new IterableConverter.Converter<TreeOperation, NodeOperation>() {
|
|
87 @Override
|
|
88 public TreeOperation conv(NodeOperation _b) {
|
|
89 return new DefaultTreeOperation(_path, _b);
|
|
90 }
|
|
91 };
|
|
92
|
|
93 Iterable<TreeOperation> iterable = new IterableConverter<TreeOperation, NodeOperation>(newLog, converter);
|
|
94 DefaultTreeOperationLog treeOperationLog = new DefaultTreeOperationLog(iterable, newLog.length());
|
149
|
95 TreeOperationLog newTmpLog = tmpLog.append(treeOperationLog);
|
|
96 IndexJungleTreeEditor newIndexTreeEditor = new IndexJungleTreeEditor(newNode, oldRoot, txManager, this.editor, log,
|
|
97 newTmpLog, index, parentIndex);
|
146
|
98 return DefaultEither.newB(newIndexTreeEditor);
|
145
|
99 }
|
|
100
|
|
101 @Override
|
|
102 public Either<Error, JungleTreeEditor> addNewChildAt(NodePath _path, int _pos) {
|
|
103 AppendChildAt appendChildAt = new AppendChildAt(_pos);
|
146
|
104 IndexEditor indexEditor = new DefaultIndexEditor(index);
|
145
|
105 Either<Error, IndexJungleTreeEditor> either = _edit(_path, appendChildAt, indexEditor);
|
|
106 Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(either.b());
|
|
107 return newEither;
|
|
108 }
|
118
|
109
|
145
|
110 @Override
|
|
111 public Either<Error, JungleTreeEditor> deleteChildAt(NodePath _path, int _pos) {
|
|
112 DeleteChildAt deleteChildAt = new DeleteChildAt(_pos);
|
146
|
113 DeleteChildIndexEditor indexEditor = new DeleteChildIndexEditor(_pos, index);
|
145
|
114 Either<Error, IndexJungleTreeEditor> either = _edit(_path, deleteChildAt, indexEditor);
|
|
115 JungleTreeEditor editor = either.b();
|
|
116 Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(editor);
|
|
117 return newEither;
|
|
118 }
|
118
|
119
|
145
|
120 @Override
|
|
121 public Either<Error, JungleTreeEditor> putAttribute(NodePath _path, String _key, ByteBuffer _value) {
|
|
122 PutAttribute putAttribute = new PutAttribute(_key, _value);
|
146
|
123 IndexEditor indexEditor = new DefaultIndexEditor(index);
|
145
|
124 Either<Error, IndexJungleTreeEditor> either = _edit(_path, putAttribute, indexEditor);
|
|
125 JungleTreeEditor editor = either.b();
|
|
126 Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(editor);
|
|
127 return newEither;
|
|
128 }
|
118
|
129
|
145
|
130 @Override
|
|
131 public Either<Error, JungleTreeEditor> deleteAttribute(NodePath _path, String _key) {
|
|
132 DeleteAttribute deleteAttribute = new DeleteAttribute(_key);
|
146
|
133 IndexEditor indexEditor = new DefaultIndexEditor(index);
|
145
|
134 Either<Error, IndexJungleTreeEditor> either = _edit(_path, deleteAttribute, indexEditor);
|
|
135 Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(either.b());
|
|
136 return newEither;
|
|
137 }
|
118
|
138
|
145
|
139 @Override
|
|
140 public Either<Error, JungleTreeEditor> edit(NodePath _path, NodeEditor _editor) {
|
146
|
141 IndexEditor indexEditor = new DefaultIndexEditor(index);
|
145
|
142 Either<Error, IndexJungleTreeEditor> either = _edit(_path, _editor, indexEditor);
|
|
143 JungleTreeEditor editor = either.b();
|
|
144 Either<Error, JungleTreeEditor> newEither = DefaultEither.newB(editor);
|
|
145 return newEither;
|
|
146 }
|
|
147
|
|
148 @Override
|
|
149 public Either<Error, JungleTreeEditor> success() {
|
149
|
150 ParentIndex newParentIndex = editParentIndex(tmpLog);
|
|
151 TreeOperationLog newLog = log.append(tmpLog);
|
|
152 Either<Error, TransactionManager> either = txManager.commit(root, newLog, index, newParentIndex);
|
145
|
153 if (either.isA()) {
|
|
154 return DefaultEither.newA(either.a());
|
|
155 }
|
|
156
|
149
|
157 TransactionManager newTxManager = either.b();
|
|
158 JungleTreeEditor newTreeEditor = new IndexJungleTreeEditor(root, root, newTxManager, editor, index, parentIndex);
|
118
|
159
|
145
|
160 return DefaultEither.newB(newTreeEditor);
|
|
161 }
|
|
162
|
149
|
163 private ParentIndex editParentIndex(TreeOperationLog tmpLog) {
|
|
164 TreeMap<TreeNode, TreeNode> putParentNodeMap = TreeMap.empty(TreeMapOrd.treeNodeOrd);
|
|
165 TreeMap<TreeNode, TreeNode> deleteParentNodeMap = TreeMap.empty(TreeMapOrd.treeNodeOrd);
|
|
166 for (TreeOperation log : tmpLog) {
|
|
167
|
|
168 NodePath targetNodePath = log.getNodePath();
|
|
169 putParentNodeMap = getTargetNode(TreeMap.empty(TreeMapOrd.treeNodeOrd), root, targetNodePath);
|
|
170 deleteParentNodeMap = getTargetNode(TreeMap.empty(TreeMapOrd.treeNodeOrd), oldRoot, targetNodePath);
|
|
171 System.out.println(log.getNodePath().toString());
|
|
172 }
|
|
173
|
|
174 ParentIndex newParentIndex = parentIndex;
|
|
175 if (!deleteParentNodeMap.isEmpty())
|
|
176 newParentIndex = deleteParentIndex(putParentNodeMap, newParentIndex);
|
|
177
|
|
178
|
|
179 if (!putParentNodeMap.isEmpty())
|
|
180 newParentIndex = putParentIndex(putParentNodeMap,newParentIndex);
|
|
181
|
|
182 return newParentIndex;
|
|
183 }
|
|
184
|
|
185 private ParentIndex deleteParentIndex(TreeMap<TreeNode, TreeNode> deleteParentNodeMap, ParentIndex editParentIndex) {
|
|
186 Iterator<P2<TreeNode, TreeNode>> parentNodeIterator = deleteParentNodeMap.iterator();
|
|
187 ParentIndex newParentIndex = editParentIndex;
|
|
188
|
|
189 for (; parentNodeIterator.hasNext();) {
|
|
190 TreeNode parentNode = parentNodeIterator.next()._1();
|
|
191 TreeNodeChildren children = parentNode.getChildren();
|
|
192 Iterator<TreeNode> childrenIterator = children.iterator();
|
|
193
|
|
194 for (; childrenIterator.hasNext();) {
|
|
195 TreeNode child = childrenIterator.next();
|
|
196 newParentIndex = newParentIndex.delete(child);
|
|
197 }
|
|
198 }
|
|
199 return newParentIndex;
|
|
200 }
|
|
201
|
|
202 private ParentIndex putParentIndex(TreeMap<TreeNode, TreeNode> putParentNodeMap,ParentIndex editParentIndex) {
|
|
203 Iterator<P2<TreeNode, TreeNode>> parentNodeIterator = putParentNodeMap.iterator();
|
|
204 ParentIndex newParentIndex = editParentIndex;
|
|
205
|
|
206 for (; parentNodeIterator.hasNext();) {
|
|
207 TreeNode parentNode = parentNodeIterator.next()._1();
|
|
208 TreeNodeChildren children = parentNode.getChildren();
|
|
209 Iterator<TreeNode> childrenIterator = children.iterator();
|
|
210
|
|
211 for (; childrenIterator.hasNext();) {
|
|
212 TreeNode child = childrenIterator.next();
|
|
213 newParentIndex = newParentIndex.set(child, parentNode);
|
|
214 }
|
|
215 }
|
|
216 return newParentIndex;
|
|
217 }
|
|
218
|
|
219 private TreeMap<TreeNode, TreeNode> getTargetNode(TreeMap<TreeNode, TreeNode> treeNodeMap, TreeNode node,
|
|
220 NodePath path) {
|
|
221 if (path.size() == 0)
|
|
222 return treeNodeMap;
|
|
223
|
|
224 Pair<Integer, NodePath> pathNode = path.pop();
|
|
225
|
|
226 if (pathNode.left() == -1) {
|
|
227 TreeMap<TreeNode, TreeNode> newTreeNodeMap = treeNodeMap.set(node, node);
|
|
228 return getTargetNode(newTreeNodeMap, node, pathNode.right());
|
|
229 }
|
|
230
|
|
231 Either<Error, TreeNode> either = node.getChildren().at(pathNode.left());
|
|
232 if (either.isA())
|
|
233 return treeNodeMap;
|
|
234
|
|
235 TreeNode child = either.b();
|
|
236 TreeMap<TreeNode, TreeNode> newTreeNodeMap = treeNodeMap.set(child, child);
|
|
237 if (pathNode.right().size() == 0)
|
|
238 return newTreeNodeMap;
|
|
239
|
|
240 return getTargetNode(newTreeNodeMap, child, pathNode.right());
|
|
241
|
|
242 }
|
|
243
|
145
|
244 @Override
|
|
245 public String getID() {
|
|
246 return txManager.getUUID();
|
|
247 }
|
118
|
248
|
145
|
249 @Override
|
|
250 public String getRevision() {
|
|
251 return Long.toString(txManager.getRevision());
|
|
252 }
|
118
|
253
|
145
|
254 @Override
|
|
255 public TreeNode getRoot() {
|
|
256 return root;
|
|
257 }
|
118
|
258
|
|
259 } |