Mercurial > hg > Members > shoshi > TreeCMSv2
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 } |