Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: pkg/analysis_server/lib/src/index/page_node_manager.dart

Issue 326123002: Node cache, binary search. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library index.page_node_manager; 5 library index.page_node_manager;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:typed_data'; 8 import 'dart:typed_data';
9 9
10 import 'package:analysis_server/src/index/lru_cache.dart';
11
10 import 'b_plus_tree.dart'; 12 import 'b_plus_tree.dart';
11 13
12 14
13 /** 15 /**
16 * A [NodeManager] that caches a specified number of index and leaf nodes.
17 */
18 class CachingNodeManager<K, V, N> implements NodeManager<K, V, N> {
19 final NodeManager<K, V, N> _delegate;
20 LRUCache<N, IndexNodeData<K, N>> _indexCache;
21 LRUCache<N, LeafNodeData<K, V>> _leafCache;
22
23 CachingNodeManager(this._delegate, int indexNodeCacheSize,
24 int leafNodeCacheSize) {
25 // TODO(scheglov) method pointers don't work with mocks
26 // _indexCache = new LRUCache<N, IndexNodeData<K, N>>(indexNodeCacheSize,
27 // _delegate.writeIndex);
28 // _leafCache = new LRUCache<N, LeafNodeData<K, V>>(leafNodeCacheSize,
29 // _delegate.writeLeaf);
30 _indexCache = new LRUCache<N, IndexNodeData<K, N>>(indexNodeCacheSize,
31 (N key, IndexNodeData<K, N> value) {
32 _delegate.writeIndex(key, value);
33 });
34 _leafCache = new LRUCache<N, LeafNodeData<K, V>>(leafNodeCacheSize, (N key,
35 LeafNodeData<K, V> value) {
36 _delegate.writeLeaf(key, value);
37 });
38 }
39
40 @override
41 int get maxIndexKeys => _delegate.maxIndexKeys;
42
43 @override
44 int get maxLeafKeys => _delegate.maxLeafKeys;
45
46 @override
47 N createIndex() {
48 return _delegate.createIndex();
49 }
50
51 @override
52 N createLeaf() {
53 return _delegate.createLeaf();
54 }
55
56 @override
57 void delete(N id) {
58 _indexCache.remove(id);
59 _leafCache.remove(id);
60 _delegate.delete(id);
61 }
62
63 @override
64 bool isIndex(N id) {
65 return _delegate.isIndex(id);
66 }
67
68 @override
69 IndexNodeData<K, N> readIndex(N id) {
70 IndexNodeData<K, N> data = _indexCache.get(id);
71 if (data != null) {
72 return data;
73 }
74 return _delegate.readIndex(id);
75 }
76
77 @override
78 LeafNodeData<K, V> readLeaf(N id) {
79 LeafNodeData<K, V> data = _leafCache.get(id);
80 if (data != null) {
81 return data;
82 }
83 return _delegate.readLeaf(id);
84 }
85
86 @override
87 void writeIndex(N id, IndexNodeData<K, N> data) {
88 _indexCache.put(id, data);
89 }
90
91 @override
92 void writeLeaf(N id, LeafNodeData<K, V> data) {
93 _leafCache.put(id, data);
94 }
95 }
96
97
98 /**
14 * A [Codec] encodes and decodes data. 99 * A [Codec] encodes and decodes data.
15 */ 100 */
16 abstract class Codec<E> { 101 abstract class Codec<E> {
17 /** 102 /**
18 * The size of the value in bytes. 103 * The size of the value in bytes.
19 */ 104 */
20 int get sizeInBytes; 105 int get sizeInBytes;
21 106
22 /** 107 /**
23 * Returns the value decoded from [buffer]. 108 * Returns the value decoded from [buffer].
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 145
61 @override 146 @override
62 void encode(ByteData buffer, String value) { 147 void encode(ByteData buffer, String value) {
63 int length = value.length; 148 int length = value.length;
64 if (length > maxLength) { 149 if (length > maxLength) {
65 throw new ArgumentError( 150 throw new ArgumentError(
66 'String $value length=$length is greater than allowed $maxLength'); 151 'String $value length=$length is greater than allowed $maxLength');
67 } 152 }
68 buffer.setUint16(0, length); 153 buffer.setUint16(0, length);
69 int offset = 2; 154 int offset = 2;
70 for (int codeUnit in value.codeUnits) { 155 List<int> codeUnits = value.codeUnits;
71 buffer.setUint16(offset, codeUnit); 156 for (int i = 0; i < length; i++) {
157 buffer.setUint16(offset, codeUnits[i]);
72 offset += 2; 158 offset += 2;
73 } 159 }
74 } 160 }
75 } 161 }
76 162
77 163
78 /** 164 /**
79 * A [PageManager] that keeps all [Uint8List] pages in memory. 165 * A [PageManager] that keeps all [Uint8List] pages in memory.
80 */ 166 */
81 class MemoryPageManager implements PageManager { 167 class MemoryPageManager implements PageManager {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 239
154 /** 240 /**
155 * A [NodeManager] that keeps nodes in [PageManager]. 241 * A [NodeManager] that keeps nodes in [PageManager].
156 */ 242 */
157 class PageNodeManager<K, V> implements NodeManager<K, V, int> { 243 class PageNodeManager<K, V> implements NodeManager<K, V, int> {
158 static const int INDEX_OFFSET_DATA = 4; 244 static const int INDEX_OFFSET_DATA = 4;
159 static const int INDEX_OFFSET_KEY_COUNT = 0; 245 static const int INDEX_OFFSET_KEY_COUNT = 0;
160 static const int LEAF_OFFSET_DATA = 4; 246 static const int LEAF_OFFSET_DATA = 4;
161 static const int LEAF_OFFSET_KEY_COUNT = 0; 247 static const int LEAF_OFFSET_KEY_COUNT = 0;
162 248
163 final Set<int> indexPages = new HashSet<int>(); 249 final Set<int> _indexPages = new HashSet<int>();
164 Codec<K> keyCodec; 250 Codec<K> _keyCodec;
165 final Set<int> leafPages = new HashSet<int>(); 251 final Set<int> _leafPages = new HashSet<int>();
166 PageManager pageManager; 252 PageManager _pageManager;
167 Codec<V> valueCodec; 253 Codec<V> _valueCodec;
168 254
169 PageNodeManager(this.pageManager, this.keyCodec, this.valueCodec); 255 PageNodeManager(this._pageManager, this._keyCodec, this._valueCodec);
170 256
171 @override 257 @override
172 int get maxIndexKeys { 258 int get maxIndexKeys {
173 int keySize = keyCodec.sizeInBytes; 259 int keySize = _keyCodec.sizeInBytes;
174 int childSize = 4; 260 int childSize = 4;
175 int dataSize = pageManager.pageSizeInBytes - INDEX_OFFSET_DATA; 261 int dataSize = _pageManager.pageSizeInBytes - INDEX_OFFSET_DATA;
176 return (dataSize - childSize) ~/ (keySize + childSize); 262 return (dataSize - childSize) ~/ (keySize + childSize);
177 } 263 }
178 264
179 @override 265 @override
180 int get maxLeafKeys { 266 int get maxLeafKeys {
181 int keySize = keyCodec.sizeInBytes; 267 int keySize = _keyCodec.sizeInBytes;
182 int valueSize = valueCodec.sizeInBytes; 268 int valueSize = _valueCodec.sizeInBytes;
183 int dataSize = pageManager.pageSizeInBytes - INDEX_OFFSET_DATA; 269 int dataSize = _pageManager.pageSizeInBytes - INDEX_OFFSET_DATA;
184 return dataSize ~/ (keySize + valueSize); 270 return dataSize ~/ (keySize + valueSize);
185 } 271 }
186 272
187 @override 273 @override
188 int createIndex() { 274 int createIndex() {
189 int id = pageManager.alloc(); 275 int id = _pageManager.alloc();
190 indexPages.add(id); 276 _indexPages.add(id);
191 return id; 277 return id;
192 } 278 }
193 279
194 @override 280 @override
195 int createLeaf() { 281 int createLeaf() {
196 int id = pageManager.alloc(); 282 int id = _pageManager.alloc();
197 leafPages.add(id); 283 _leafPages.add(id);
198 return id; 284 return id;
199 } 285 }
200 286
201 @override 287 @override
202 void delete(int id) { 288 void delete(int id) {
203 pageManager.free(id); 289 _pageManager.free(id);
204 indexPages.remove(id); 290 _indexPages.remove(id);
205 leafPages.remove(id); 291 _leafPages.remove(id);
206 } 292 }
207 293
208 @override 294 @override
209 bool isIndex(int id) { 295 bool isIndex(int id) {
210 return indexPages.contains(id); 296 return _indexPages.contains(id);
211 } 297 }
212 298
213 @override 299 @override
214 IndexNodeData<K, int> readIndex(int id) { 300 IndexNodeData<K, int> readIndex(int id) {
215 Uint8List page = pageManager.read(id); 301 Uint8List page = _pageManager.read(id);
216 // read header 302 // read header
217 int keyCount; 303 int keyCount;
218 { 304 {
219 ByteData data = new ByteData.view(page.buffer); 305 ByteData data = new ByteData.view(page.buffer);
220 keyCount = data.getInt32(INDEX_OFFSET_KEY_COUNT); 306 keyCount = data.getInt32(INDEX_OFFSET_KEY_COUNT);
221 } 307 }
222 // read keys/children 308 // read keys/children
223 List<K> keys = new List<K>(); 309 List<K> keys = new List<K>();
224 List<int> children = new List<int>(); 310 List<int> children = new List<int>();
225 int keySize = keyCodec.sizeInBytes; 311 int keySize = _keyCodec.sizeInBytes;
226 int offset = INDEX_OFFSET_DATA; 312 int offset = INDEX_OFFSET_DATA;
227 for (int i = 0; i < keyCount; i++) { 313 for (int i = 0; i < keyCount; i++) {
228 // read child 314 // read child
229 { 315 {
230 ByteData byteData = new ByteData.view(page.buffer, offset); 316 ByteData byteData = new ByteData.view(page.buffer, offset);
231 int childPage = byteData.getUint32(0); 317 int childPage = byteData.getUint32(0);
232 children.add(childPage); 318 children.add(childPage);
233 offset += 4; 319 offset += 4;
234 } 320 }
235 // read key 321 // read key
236 { 322 {
237 ByteData byteData = new ByteData.view(page.buffer, offset, keySize); 323 ByteData byteData = new ByteData.view(page.buffer, offset, keySize);
238 K key = keyCodec.decode(byteData); 324 K key = _keyCodec.decode(byteData);
239 keys.add(key); 325 keys.add(key);
240 offset += keySize; 326 offset += keySize;
241 } 327 }
242 } 328 }
243 // read last child 329 // read last child
244 { 330 {
245 ByteData byteData = new ByteData.view(page.buffer, offset); 331 ByteData byteData = new ByteData.view(page.buffer, offset);
246 int childPage = byteData.getUint32(0); 332 int childPage = byteData.getUint32(0);
247 children.add(childPage); 333 children.add(childPage);
248 } 334 }
249 // done 335 // done
250 return new IndexNodeData<K, int>(keys, children); 336 return new IndexNodeData<K, int>(keys, children);
251 } 337 }
252 338
253 @override 339 @override
254 LeafNodeData<K, V> readLeaf(int id) { 340 LeafNodeData<K, V> readLeaf(int id) {
255 Uint8List page = pageManager.read(id); 341 Uint8List page = _pageManager.read(id);
256 // read header 342 // read header
257 int keyCount; 343 int keyCount;
258 { 344 {
259 ByteData data = new ByteData.view(page.buffer); 345 ByteData data = new ByteData.view(page.buffer);
260 keyCount = data.getInt32(LEAF_OFFSET_KEY_COUNT); 346 keyCount = data.getInt32(LEAF_OFFSET_KEY_COUNT);
261 } 347 }
262 // read keys/children 348 // read keys/children
263 List<K> keys = new List<K>(); 349 List<K> keys = new List<K>();
264 List<V> values = new List<V>(); 350 List<V> values = new List<V>();
265 int keySize = keyCodec.sizeInBytes; 351 int keySize = _keyCodec.sizeInBytes;
266 int valueSize = valueCodec.sizeInBytes; 352 int valueSize = _valueCodec.sizeInBytes;
267 int offset = LEAF_OFFSET_DATA; 353 int offset = LEAF_OFFSET_DATA;
268 for (int i = 0; i < keyCount; i++) { 354 for (int i = 0; i < keyCount; i++) {
269 // read key 355 // read key
270 { 356 {
271 ByteData byteData = new ByteData.view(page.buffer, offset, keySize); 357 ByteData byteData = new ByteData.view(page.buffer, offset, keySize);
272 K key = keyCodec.decode(byteData); 358 K key = _keyCodec.decode(byteData);
273 keys.add(key); 359 keys.add(key);
274 offset += keySize; 360 offset += keySize;
275 } 361 }
276 // read value 362 // read value
277 { 363 {
278 ByteData byteData = new ByteData.view(page.buffer, offset); 364 ByteData byteData = new ByteData.view(page.buffer, offset);
279 V value = valueCodec.decode(byteData); 365 V value = _valueCodec.decode(byteData);
280 values.add(value); 366 values.add(value);
281 offset += valueSize; 367 offset += valueSize;
282 } 368 }
283 } 369 }
284 // done 370 // done
285 return new LeafNodeData<K, V>(keys, values); 371 return new LeafNodeData<K, V>(keys, values);
286 } 372 }
287 373
288 @override 374 @override
289 void writeIndex(int id, IndexNodeData<K, int> data) { 375 void writeIndex(int id, IndexNodeData<K, int> data) {
290 Uint8List page = new Uint8List(pageManager.pageSizeInBytes); 376 Uint8List page = new Uint8List(_pageManager.pageSizeInBytes);
291 // write header 377 // write header
292 int keyCount = data.keys.length; 378 int keyCount = data.keys.length;
293 { 379 {
294 ByteData byteData = new ByteData.view(page.buffer); 380 ByteData byteData = new ByteData.view(page.buffer);
295 byteData.setUint32(INDEX_OFFSET_KEY_COUNT, keyCount); 381 byteData.setUint32(PageNodeManager.INDEX_OFFSET_KEY_COUNT, keyCount);
296 } 382 }
297 // write keys/children 383 // write keys/children
298 int keySize = keyCodec.sizeInBytes; 384 int keySize = _keyCodec.sizeInBytes;
299 int offset = INDEX_OFFSET_DATA; 385 int offset = PageNodeManager.INDEX_OFFSET_DATA;
300 for (int i = 0; i < keyCount; i++) { 386 for (int i = 0; i < keyCount; i++) {
301 // write child 387 // write child
302 { 388 {
303 ByteData byteData = new ByteData.view(page.buffer, offset); 389 ByteData byteData = new ByteData.view(page.buffer, offset);
304 byteData.setUint32(0, data.children[i]); 390 byteData.setUint32(0, data.children[i]);
305 offset += 4; 391 offset += 4;
306 } 392 }
307 // write key 393 // write key
308 { 394 {
309 ByteData byteData = new ByteData.view(page.buffer, offset, keySize); 395 ByteData byteData = new ByteData.view(page.buffer, offset, keySize);
310 keyCodec.encode(byteData, data.keys[i]); 396 _keyCodec.encode(byteData, data.keys[i]);
311 offset += keySize; 397 offset += keySize;
312 } 398 }
313 } 399 }
314 // write last child 400 // write last child
315 { 401 {
316 ByteData byteData = new ByteData.view(page.buffer, offset); 402 ByteData byteData = new ByteData.view(page.buffer, offset);
317 byteData.setUint32(0, data.children.last); 403 byteData.setUint32(0, data.children.last);
318 } 404 }
319 // write page 405 // write page
320 pageManager.write(id, page); 406 _pageManager.write(id, page);
321 } 407 }
322 408
323 @override 409 @override
324 void writeLeaf(int id, LeafNodeData<K, V> data) { 410 void writeLeaf(int id, LeafNodeData<K, V> data) {
325 Uint8List page = new Uint8List(pageManager.pageSizeInBytes); 411 Uint8List page = new Uint8List(_pageManager.pageSizeInBytes);
326 // write header 412 // write header
327 int keyCount = data.keys.length; 413 int keyCount = data.keys.length;
328 { 414 {
329 ByteData byteData = new ByteData.view(page.buffer); 415 ByteData byteData = new ByteData.view(page.buffer);
330 byteData.setUint32(LEAF_OFFSET_KEY_COUNT, keyCount); 416 byteData.setUint32(PageNodeManager.LEAF_OFFSET_KEY_COUNT, keyCount);
331 } 417 }
332 // write keys/values 418 // write keys/values
333 int keySize = keyCodec.sizeInBytes; 419 int keySize = _keyCodec.sizeInBytes;
334 int valueSize = valueCodec.sizeInBytes; 420 int valueSize = _valueCodec.sizeInBytes;
335 int offset = LEAF_OFFSET_DATA; 421 int offset = PageNodeManager.LEAF_OFFSET_DATA;
336 for (int i = 0; i < keyCount; i++) { 422 for (int i = 0; i < keyCount; i++) {
337 // write key 423 // write key
338 { 424 {
339 ByteData byteData = new ByteData.view(page.buffer, offset, keySize); 425 ByteData byteData = new ByteData.view(page.buffer, offset, keySize);
340 keyCodec.encode(byteData, data.keys[i]); 426 _keyCodec.encode(byteData, data.keys[i]);
341 offset += keySize; 427 offset += keySize;
342 } 428 }
343 // write value 429 // write value
344 { 430 {
345 ByteData byteData = new ByteData.view(page.buffer, offset); 431 ByteData byteData = new ByteData.view(page.buffer, offset);
346 valueCodec.encode(byteData, data.values[i]); 432 _valueCodec.encode(byteData, data.values[i]);
347 offset += valueSize; 433 offset += valueSize;
348 } 434 }
349 } 435 }
350 // write page 436 // write page
351 pageManager.write(id, page); 437 _pageManager.write(id, page);
352 } 438 }
353 } 439 }
354 440
355 441
356 /** 442 /**
357 * A [Codec] for unsigned 32-bit integers. 443 * A [Codec] for unsigned 32-bit integers.
358 */ 444 */
359 class Uint32Codec implements Codec<int> { 445 class Uint32Codec implements Codec<int> {
360 static const Uint32Codec INSTANCE = const Uint32Codec._(); 446 static const Uint32Codec INSTANCE = const Uint32Codec._();
361 447
362 const Uint32Codec._(); 448 const Uint32Codec._();
363 449
364 @override 450 @override
365 int get sizeInBytes => 4; 451 int get sizeInBytes => 4;
366 452
367 @override 453 @override
368 int decode(ByteData buffer) { 454 int decode(ByteData buffer) {
369 return buffer.getUint32(0); 455 return buffer.getUint32(0);
370 } 456 }
371 457
372 @override 458 @override
373 void encode(ByteData buffer, int element) { 459 void encode(ByteData buffer, int element) {
374 buffer.setUint32(0, element); 460 buffer.setUint32(0, element);
375 } 461 }
376 } 462 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698