comparison src/treecms/memory/OnMemoryMonotonicTreeNode.java @ 22:fa784faafc78

commit
author shoshi
date Tue, 07 Jun 2011 16:42:49 +0900
parents f3150b37f9be
children 77a894c0b919
comparison
equal deleted inserted replaced
21:f3150b37f9be 22:fa784faafc78
1 package treecms.memory; 1 package treecms.memory;
2 2
3 import java.nio.ByteBuffer; 3 import java.nio.ByteBuffer;
4 4
5 import java.util.ArrayList;
6 import java.util.Collections;
5 import java.util.Iterator; 7 import java.util.Iterator;
6 import java.util.List; 8 import java.util.List;
7 import java.util.Map; 9 import java.util.Map;
8 import java.util.Set; 10 import java.util.Set;
11 import java.util.concurrent.Callable;
9 import java.util.concurrent.ConcurrentHashMap; 12 import java.util.concurrent.ConcurrentHashMap;
13 import java.util.concurrent.ConcurrentMap;
14 import java.util.concurrent.FutureTask;
10 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; 15 import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
11 16
12 import treecms.api.Forest; 17 import treecms.api.Forest;
13 import treecms.api.MonotonicTreeNode; 18 import treecms.api.MonotonicTreeNode;
14 import treecms.api.Node; 19 import treecms.api.Node;
22 * SingleLinkedなNodeをラップしたDoubleLinkedなNodeの実装です. 27 * SingleLinkedなNodeをラップしたDoubleLinkedなNodeの実装です.
23 * @author shoshi 28 * @author shoshi
24 */ 29 */
25 public class OnMemoryMonotonicTreeNode implements MonotonicTreeNode 30 public class OnMemoryMonotonicTreeNode implements MonotonicTreeNode
26 { 31 {
27 private Node m_node; 32 private String m_node;
28
29 private static final AtomicReferenceFieldUpdater<OnMemoryMonotonicTreeNode,OnMemoryMonotonicTreeNode> m_parentUpdater
30 = AtomicReferenceFieldUpdater.newUpdater(OnMemoryMonotonicTreeNode.class,OnMemoryMonotonicTreeNode.class,"m_parent");
31
32 private OnMemoryMonotonicTreeNode m_parent; 33 private OnMemoryMonotonicTreeNode m_parent;
33 34 private final OnMemoryMonotonicTree m_tree;
34 private final Map<String,OnMemoryMonotonicTreeNode> m_cache; 35 private final ConcurrentMap<String,MonotonicTreeNode> m_cache;
35 36
36 public OnMemoryMonotonicTreeNode(OnMemoryNode _target,OnMemoryMonotonicTreeNode _parent) 37 public OnMemoryMonotonicTreeNode(String _fid,OnMemoryMonotonicTreeNode _parent,OnMemoryMonotonicTree _tree)
37 { 38 {
38 m_node = _target; 39 m_node = _fid;
39 m_parent = _parent; 40 m_parent = _parent;
40 m_cache = new ConcurrentHashMap<String,OnMemoryMonotonicTreeNode>(); 41 m_cache = new ConcurrentHashMap<String,MonotonicTreeNode>();
42 m_tree = _tree;
41 } 43 }
42 44
43 @Override 45 @Override
44 public NodeID getID() 46 public NodeID getID()
45 { 47 {
46 return m_node.getID(); 48 OnMemoryNode n = m_tree.get(m_node);
47 } 49 return n.getID();
48
49 @Override
50 public Forest getForest()
51 {
52 return m_node.getForest();
53 } 50 }
54 51
55 @Override 52 @Override
56 public MonotonicTreeNode getParent() 53 public MonotonicTreeNode getParent()
57 { 54 {
58 return m_parent; 55 synchronized(m_parent){
56 OnMemoryNode node = (OnMemoryNode)getNode();
57
58 //check , does parent contain the node.
59 if(!m_parent.contains(node.getID())){
60 m_parent = null;
61 }
62 return m_parent;
63 }
59 } 64 }
60 65
61 @Override 66 @Override
62 public ByteBuffer get(ByteBuffer _key) 67 public ByteBuffer get(ByteBuffer _key)
63 { 68 {
64 return m_node.get(_key); 69 return m_tree.get(m_node).get(_key);
65 } 70 }
66 71
67 @Override 72 @Override
68 public NodeAttributes getAll() 73 public NodeAttributes getAll()
69 { 74 {
70 return m_node.getAll(); 75 return m_tree.get(m_node).getAll();
71 } 76 }
72 77
73 @Override 78 @Override
74 public synchronized void put(ByteBuffer _key, ByteBuffer _value) 79 public synchronized void put(ByteBuffer _key, ByteBuffer _value)
75 { 80 {
76 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 81 OnMemoryNode n = m_tree.get(m_node);
82 NodeData<Node> d = new NodeData<Node>(n,n);
77 d.put(_key,_value); 83 d.put(_key,_value);
78 84
79 cloneAndTransmit(d); 85 cloneAndTransmit(d);
80 } 86 }
81 87
82 @Override 88 @Override
83 public synchronized void putAll(NodeAttributes _map) 89 public synchronized void putAll(NodeAttributes _map)
84 { 90 {
85 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 91 OnMemoryNode n = m_tree.get(m_node);
92 NodeData<Node> d = new NodeData<Node>(n,n);
86 d.putAll(_map); 93 d.putAll(_map);
87 94
88 cloneAndTransmit(d); 95 cloneAndTransmit(d);
89 } 96 }
90 97
91 @Override 98 @Override
92 public synchronized void remove(ByteBuffer _key) 99 public synchronized void remove(ByteBuffer _key)
93 { 100 {
94 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 101 OnMemoryNode n = m_tree.get(m_node);
102 NodeData<Node> d = new NodeData<Node>(n,n);
95 d.remove(_key); 103 d.remove(_key);
96 104
97 cloneAndTransmit(d); 105 cloneAndTransmit(d);
98 } 106 }
99 107
100 @Override 108 @Override
101 public synchronized void removeAll(Set<ByteBuffer> _keys) 109 public synchronized void removeAll(Set<ByteBuffer> _keys)
102 { 110 {
103 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 111 OnMemoryNode n = m_tree.get(m_node);
112 NodeData<Node> d = new NodeData<Node>(n,n);
104 d.removeAll(_keys); 113 d.removeAll(_keys);
105 114
106 cloneAndTransmit(d); 115 cloneAndTransmit(d);
107 } 116 }
108 117
109 @Override 118 @Override
110 public synchronized void clearAttributes() 119 public synchronized void clearAttributes()
111 { 120 {
112 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 121 OnMemoryNode n = m_tree.get(m_node);
122 NodeData<Node> d = new NodeData<Node>(n,n);
113 d.clearAttributes(); 123 d.clearAttributes();
114 124
115 cloneAndTransmit(d); 125 cloneAndTransmit(d);
116 } 126 }
117 127
118 public synchronized void cloneAndTransmit(NodeData<Node> _d) 128 public synchronized void cloneAndTransmit(NodeData<Node> _d)
119 { 129 {
120 OnMemoryForest f = (OnMemoryForest)m_node.getForest(); 130 OnMemoryNode node = m_tree.get(m_node);
121 Node clone = f.createNode(m_node.getID().update(),_d); 131 Node clone = m_tree.createNode(node.getID().update(),_d);
122 transmit(m_node,clone); 132 transmit(node,clone);
123 133 }
124 m_node = clone; 134
125 } 135 public synchronized boolean transmit(Node _orig,Node _edit)
126 136 {
127 public synchronized void transmit(Node _orig,Node _edit) 137 OnMemoryNode node = m_tree.get(m_node);
128 { 138
129 OnMemoryForest f = (OnMemoryForest)m_node.getForest(); 139 NodeData<Node> d = new NodeData<Node>(node,node);
130 OnMemoryNode clone = f.createNode(m_node.getID().update(),null); 140 if(!d.contains(_edit.getID())){
131 clone.replace(_edit); 141
132 142 }
133 if(m_parent != null){ 143 d.replace(_edit);
134 m_parent.transmit(m_node,(OnMemoryNode)clone); 144
135 return; 145 OnMemoryNode clone = m_tree.createNode(node.getID().update(),null);
136 } 146
137 } 147
138 148 OnMemoryMonotonicTreeNode parent = (OnMemoryMonotonicTreeNode)getParent();
139 private synchronized OnMemoryMonotonicTreeNode getCache(OnMemoryNode _node) 149 if(parent != null){
140 { 150 return m_parent.transmit(node,clone);
141 NodeID id = _node.getID(); 151 }
142 OnMemoryMonotonicTreeNode mono; 152 return true;
143 synchronized(m_cache){
144 mono = m_cache.get(id);
145 if(mono == null){
146 //cache not found . create it
147 mono = new OnMemoryMonotonicTreeNode(_node,this);
148 }
149 }
150 return mono;
151 } 153 }
152 154
153 @Override 155 @Override
154 public synchronized Node getNode() 156 public synchronized Node getNode()
155 { 157 {
156 return m_node; 158 return m_tree.get(m_node);
157 } 159 }
158 160
159 @Override 161 @Override
160 public synchronized List<MonotonicTreeNode> getList() 162 public synchronized List<MonotonicTreeNode> getList()
161 { 163 {
162 //NodeのリストよりMonotonicTreeNodeのリストを作成する. 164 //NodeのリストよりMonotonicTreeNodeのリストを作成する.
163 NodeChildren<MonotonicTreeNode> res = new NodeChildrenImpl<MonotonicTreeNode>(); 165 OnMemoryNode node = m_tree.get(m_node);
164 for(Iterator<Node> it = m_node.getList().iterator();it.hasNext();){ 166 int size = node.getList().size();
167 ArrayList<MonotonicTreeNode> list = new ArrayList<MonotonicTreeNode>(size);
168 for(Iterator<Node> it = node.getList().iterator();it.hasNext();){
165 OnMemoryNode n = (OnMemoryNode)it.next(); 169 OnMemoryNode n = (OnMemoryNode)it.next();
166 res.add(getCache(n)); 170 list.add(getCache(n.getID().getFamilyID()));
167 } 171 }
168 172
169 return res.getList(); 173 return (List<MonotonicTreeNode>)Collections.unmodifiableCollection(list);
170 } 174 }
171 175
172 @Override 176 public OnMemoryMonotonicTreeNode getCache(final String _fid)
173 public synchronized boolean add(MonotonicTreeNode _n) 177 {
174 { 178 OnMemoryMonotonicTreeNode cache = new OnMemoryMonotonicTreeNode(m_node,this,m_tree);
175 OnMemoryMonotonicTreeNode mono = (OnMemoryMonotonicTreeNode)_n; 179 cache = (OnMemoryMonotonicTreeNode)m_cache.putIfAbsent(_fid,cache);
176 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 180
177 boolean ret = d.add(mono.m_node); 181 return cache;
178 if(ret){
179 cloneAndTransmit(d);
180 }
181
182 return ret;
183 }
184
185 @Override
186 public synchronized boolean addAll(NodeChildren<MonotonicTreeNode> _list)
187 {
188 //MotonicTreeNodeのリストからNodeのリストを作成する.
189 NodeChildren<Node> c = new NodeChildrenImpl<Node>();
190 for(Iterator<MonotonicTreeNode> it = _list.getList().iterator();it.hasNext();){
191 OnMemoryMonotonicTreeNode mono = (OnMemoryMonotonicTreeNode)it.next();
192 c.add(mono.m_node);
193 }
194
195 NodeData<Node> d = new NodeData<Node>(m_node,m_node);
196 boolean ret = d.addAll(c);
197 if(ret){
198 cloneAndTransmit(d);
199 }
200
201 return ret;
202 } 182 }
203 183
204 @Override 184 @Override
205 public synchronized MonotonicTreeNode remove(int _index) 185 public synchronized MonotonicTreeNode remove(int _index)
206 { 186 {
207 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 187 OnMemoryNode n = m_tree.get(m_node);
208 OnMemoryNode n = (OnMemoryNode) d.remove(_index); 188 NodeData<Node> d = new NodeData<Node>(n,n);
189 OnMemoryNode deleted = (OnMemoryNode) d.remove(_index);
190
209 if(n != null){ 191 if(n != null){
210 cloneAndTransmit(d); 192 cloneAndTransmit(d);
211 return new OnMemoryMonotonicTreeNode((OnMemoryNode)n,null); 193
194 OnMemoryMonotonicTreeNode tn = getCache(deleted.getID().getFamilyID());
195 return tn;
212 } 196 }
213 197
214 return null; 198 return null;
215 } 199 }
216 200
217 @Override 201 @Override
218 public synchronized void clearChildren() 202 public synchronized void clearChildren()
219 { 203 {
220 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 204 OnMemoryNode node = m_tree.get(m_node);
205 NodeData<Node> d = new NodeData<Node>(node,node);
221 d.clearChildren(); 206 d.clearChildren();
222 207
223 cloneAndTransmit(d); 208 cloneAndTransmit(d);
224 } 209 }
225 210
226 @Override 211 @Override
227 public Map<ByteBuffer, ByteBuffer> asMap() 212 public Map<ByteBuffer, ByteBuffer> asMap()
228 { 213 {
229 return m_node.asMap(); 214 OnMemoryNode node = m_tree.get(m_node);
215 return node.asMap();
230 } 216 }
231 217
232 @Override 218 @Override
233 public Set<ByteBuffer> getKeySet() 219 public Set<ByteBuffer> getKeySet()
234 { 220 {
235 return m_node.getKeySet(); 221 OnMemoryNode node = m_tree.get(m_node);
222 return node.getKeySet();
236 } 223 }
237 224
238 @Override 225 @Override
239 public synchronized MonotonicTreeNode get(int _index) 226 public synchronized MonotonicTreeNode get(int _index)
240 { 227 {
241 OnMemoryNode n = (OnMemoryNode) m_node.get(_index); 228 OnMemoryNode node = m_tree.get(m_node);
242 return getCache(n); 229 return getCache(node.getID().getFamilyID());
243 } 230 }
244 231
245 @Override 232 @Override
246 public synchronized MonotonicTreeNode replace(MonotonicTreeNode _newChild) 233 public boolean contains(NodeID _id)
247 { 234 {
248 OnMemoryMonotonicTreeNode mono = (OnMemoryMonotonicTreeNode)_newChild; 235 OnMemoryNode node = m_tree.get(m_node);
249 NodeData<Node> d = new NodeData<Node>(m_node,m_node); 236 return node.contains(_id);
250 OnMemoryNode n = (OnMemoryNode) d.replace(mono.m_node); 237 }
251 238
252 if(n != null){ 239 @Override
253 cloneAndTransmit(d); 240 public boolean swap(String _fid1,String _fid2)
254 return new OnMemoryMonotonicTreeNode(n,null); 241 {
255 } 242 OnMemoryNode node = m_tree.get(m_node);
243 return node.swap(_fid1,_fid2);
244 }
245
246 @Override
247 public Set<String> getFamilyIDSet()
248 {
249 OnMemoryNode node = m_tree.get(m_node);
250 return node.getFamilyIDSet();
251 }
252
253 @Override
254 public synchronized MonotonicTreeNode get(String _fid)
255 {
256 OnMemoryMonotonicTreeNode mono = getCache(_fid);
257 return mono;
258 }
259
260 @Override
261 public synchronized MonotonicTreeNode remove(String _fid)
262 {
263 OnMemoryMonotonicTreeNode tnode = getCache(_fid);
264 OnMemoryNode node = (OnMemoryNode)tnode.getNode();
265
266 NodeData<Node> d = new NodeData<Node>(node,node);
267 d.remove(_fid);
268
269 cloneAndTransmit(d);
270 return tnode;
271 }
272
273 @Override
274 public synchronized MonotonicTreeNode create(NodeAttributes _attr)
275 {
276 NodeID newID = getNode().getID().create();
277 OnMemoryNode newNode = new OnMemoryNode(newID,new NodeData<Node>(null,_attr));
278
279 OnMemoryNode thisNode = (OnMemoryNode)getNode();
280 NodeData<Node> d = new NodeData<Node>(thisNode,thisNode);
281 d.add(newNode);
256 282
257 return null; 283 return null;
258 } 284 }
259
260 @Override
261 public boolean contains(NodeID _id)
262 {
263 return m_node.contains(_id);
264 }
265
266 @Override
267 public boolean swap(String _fid1,String _fid2)
268 {
269 return m_node.swap(_fid1,_fid2);
270 }
271
272 @Override
273 public Set<String> getFamilyIDSet()
274 {
275 return m_node.getFamilyIDSet();
276 }
277
278 @Override
279 public synchronized MonotonicTreeNode get(String _fid)
280 {
281 OnMemoryNode n = (OnMemoryNode) m_node.get(_fid);
282 OnMemoryMonotonicTreeNode mono = getCache(n);
283
284 return mono;
285 }
286
287 @Override
288 public synchronized MonotonicTreeNode remove(String _fid)
289 {
290 NodeData<Node> d = new NodeData<Node>(m_node,m_node);
291 OnMemoryNode n = (OnMemoryNode) d.remove(_fid);
292
293 cloneAndTransmit(d);
294
295 return new OnMemoryMonotonicTreeNode(n,null);
296 }
297 } 285 }