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

Side by Side Diff: runtime/vm/hash_table.h

Issue 2083103002: Remove some uses of STL map. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
« no previous file with comments | « runtime/vm/hash_map_test.cc ('k') | runtime/vm/hash_table_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #ifndef VM_HASH_TABLE_H_ 5 #ifndef VM_HASH_TABLE_H_
6 #define VM_HASH_TABLE_H_ 6 #define VM_HASH_TABLE_H_
7 7
8 // Temporarily used when sorting the indices in EnumIndexHashTable.
9 // TODO(koda): Remove these dependencies before using in production.
10 #include <map>
11 #include <vector>
12
13 #include "platform/assert.h" 8 #include "platform/assert.h"
14 #include "vm/object.h" 9 #include "vm/object.h"
15 10
16 namespace dart { 11 namespace dart {
17 12
18 // OVERVIEW: 13 // OVERVIEW:
19 // 14 //
20 // Hash maps and hash sets all use RawArray as backing storage. At the lowest 15 // Hash maps and hash sets all use RawArray as backing storage. At the lowest
21 // level is a generic open-addressing table that supports deletion. 16 // level is a generic open-addressing table that supports deletion.
22 // - HashTable 17 // - HashTable
23 // The next layer provides ordering and iteration functionality: 18 // The next layer provides ordering and iteration functionality:
24 // - UnorderedHashTable 19 // - UnorderedHashTable
25 // - EnumIndexHashTable
26 // - LinkedListHashTable (TODO(koda): Implement.) 20 // - LinkedListHashTable (TODO(koda): Implement.)
27 // The utility class HashTables handles growth and conversion (e.g., converting 21 // The utility class HashTables handles growth and conversion.
28 // a compact EnumIndexHashTable to an iteration-efficient LinkedListHashTable).
29 // The next layer fixes the payload size and provides a natural interface: 22 // The next layer fixes the payload size and provides a natural interface:
30 // - HashMap 23 // - HashMap
31 // - HashSet 24 // - HashSet
32 // Combining either of these with an iteration strategy, we get the templates 25 // Combining either of these with an iteration strategy, we get the templates
33 // intended for use outside this file: 26 // intended for use outside this file:
34 // - UnorderedHashMap 27 // - UnorderedHashMap
35 // - EnumIndexHashMap
36 // - LinkedListHashMap 28 // - LinkedListHashMap
37 // - UnorderedHashSet 29 // - UnorderedHashSet
38 // - EnumIndexHashSet
39 // - LinkedListHashSet 30 // - LinkedListHashSet
40 // Each of these can be finally specialized with KeyTraits to support any set of 31 // Each of these can be finally specialized with KeyTraits to support any set of
41 // lookup key types (e.g., look up a char* in a set of String objects), and 32 // lookup key types (e.g., look up a char* in a set of String objects), and
42 // any equality and hash code computation. 33 // any equality and hash code computation.
43 // 34 //
44 // The classes all wrap an Array handle, and methods like HashSet::Insert can 35 // The classes all wrap an Array handle, and methods like HashSet::Insert can
45 // trigger growth into a new RawArray, updating the handle. Debug mode asserts 36 // trigger growth into a new RawArray, updating the handle. Debug mode asserts
46 // that 'Release' was called once to access the final array before destruction. 37 // that 'Release' was called once to access the final array before destruction.
47 // NOTE: The handle returned by 'Release' is cleared by ~HashTable. 38 // NOTE: The handle returned by 'Release' is cleared by ~HashTable.
48 // 39 //
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 419
429 private: 420 private:
430 const UnorderedHashTable* table_; 421 const UnorderedHashTable* table_;
431 intptr_t entry_; 422 intptr_t entry_;
432 }; 423 };
433 424
434 // No extra book-keeping needed for Initialize, InsertKey, DeleteEntry. 425 // No extra book-keeping needed for Initialize, InsertKey, DeleteEntry.
435 }; 426 };
436 427
437 428
438 // Table with insertion order, using one payload component for the enumeration
439 // index, and one metadata element for the next enumeration index.
440 template<typename KeyTraits, intptr_t kUserPayloadSize>
441 class EnumIndexHashTable
442 : public HashTable<KeyTraits, kUserPayloadSize + 1, 1> {
443 public:
444 typedef HashTable<KeyTraits, kUserPayloadSize + 1, 1> BaseTable;
445 static const intptr_t kPayloadSize = kUserPayloadSize;
446 static const intptr_t kNextEnumIndex = BaseTable::kMetaDataIndex;
447 EnumIndexHashTable(Object* key, Smi* value, Array* data)
448 : BaseTable(key, value, data) {}
449 EnumIndexHashTable(Zone* zone, RawArray* data)
450 : BaseTable(zone, data) {}
451 explicit EnumIndexHashTable(RawArray* data)
452 : BaseTable(Thread::Current()->zone(), data) {}
453 // Note: Does not check for concurrent modification.
454 class Iterator {
455 public:
456 explicit Iterator(const EnumIndexHashTable* table) : index_(-1) {
457 // TODO(koda): Use GrowableArray after adding stateful comparator support.
458 std::map<intptr_t, intptr_t> enum_to_entry;
459 for (intptr_t i = 0; i < table->NumEntries(); ++i) {
460 if (table->IsOccupied(i)) {
461 intptr_t enum_index =
462 table->GetSmiValueAt(table->PayloadIndex(i, kPayloadSize));
463 enum_to_entry[enum_index] = i;
464 }
465 }
466 for (std::map<intptr_t, intptr_t>::iterator it = enum_to_entry.begin();
467 it != enum_to_entry.end();
468 ++it) {
469 entries_.push_back(it->second);
470 }
471 }
472 bool MoveNext() {
473 if (index_ < (static_cast<intptr_t>(entries_.size() - 1))) {
474 index_++;
475 return true;
476 }
477 return false;
478 }
479 intptr_t Current() {
480 return entries_[index_];
481 }
482
483 private:
484 intptr_t index_;
485 std::vector<intptr_t> entries_;
486 };
487
488 void Initialize() const {
489 BaseTable::Initialize();
490 BaseTable::SetSmiValueAt(kNextEnumIndex, 0);
491 }
492
493 void InsertKey(intptr_t entry, const Object& key) const {
494 BaseTable::InsertKey(entry, key);
495 BaseTable::SmiHandle() =
496 Smi::New(BaseTable::GetSmiValueAt(kNextEnumIndex));
497 BaseTable::UpdatePayload(entry, kPayloadSize, BaseTable::SmiHandle());
498 // TODO(koda): Handle possible Smi overflow from repeated insert/delete.
499 BaseTable::AdjustSmiValueAt(kNextEnumIndex, 1);
500 }
501
502 // No extra book-keeping needed for DeleteEntry.
503 };
504
505
506 class HashTables : public AllStatic { 429 class HashTables : public AllStatic {
507 public: 430 public:
508 // Allocates and initializes a table. 431 // Allocates and initializes a table.
509 template<typename Table> 432 template<typename Table>
510 static RawArray* New(intptr_t initial_capacity, 433 static RawArray* New(intptr_t initial_capacity,
511 Heap::Space space = Heap::kNew) { 434 Heap::Space space = Heap::kNew) {
512 Table table(Thread::Current()->zone(), Array::New( 435 Table table(Thread::Current()->zone(), Array::New(
513 Table::ArrayLengthForNumOccupied(initial_capacity), space)); 436 Table::ArrayLengthForNumOccupied(initial_capacity), space));
514 table.Initialize(); 437 table.Initialize();
515 return table.Release().raw(); 438 return table.Release().raw();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 public: 603 public:
681 typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap; 604 typedef HashMap<UnorderedHashTable<KeyTraits, 1> > BaseMap;
682 explicit UnorderedHashMap(RawArray* data) 605 explicit UnorderedHashMap(RawArray* data)
683 : BaseMap(Thread::Current()->zone(), data) {} 606 : BaseMap(Thread::Current()->zone(), data) {}
684 UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {} 607 UnorderedHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
685 UnorderedHashMap(Object* key, Smi* value, Array* data) 608 UnorderedHashMap(Object* key, Smi* value, Array* data)
686 : BaseMap(key, value, data) {} 609 : BaseMap(key, value, data) {}
687 }; 610 };
688 611
689 612
690 template<typename KeyTraits>
691 class EnumIndexHashMap : public HashMap<EnumIndexHashTable<KeyTraits, 1> > {
692 public:
693 typedef HashMap<EnumIndexHashTable<KeyTraits, 1> > BaseMap;
694 explicit EnumIndexHashMap(RawArray* data)
695 : BaseMap(Thread::Current()->zone(), data) {}
696 EnumIndexHashMap(Zone* zone, RawArray* data) : BaseMap(zone, data) {}
697 EnumIndexHashMap(Object* key, Smi* value, Array* data)
698 : BaseMap(key, value, data) {}
699 };
700
701
702 template<typename BaseIterTable> 613 template<typename BaseIterTable>
703 class HashSet : public BaseIterTable { 614 class HashSet : public BaseIterTable {
704 public: 615 public:
705 explicit HashSet(RawArray* data) 616 explicit HashSet(RawArray* data)
706 : BaseIterTable(Thread::Current()->zone(), data) {} 617 : BaseIterTable(Thread::Current()->zone(), data) {}
707 HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {} 618 HashSet(Zone* zone, RawArray* data) : BaseIterTable(zone, data) {}
708 HashSet(Object* key, Smi* value, Array* data) 619 HashSet(Object* key, Smi* value, Array* data)
709 : BaseIterTable(key, value, data) {} 620 : BaseIterTable(key, value, data) {}
710 bool Insert(const Object& key) { 621 bool Insert(const Object& key) {
711 EnsureCapacity(); 622 EnsureCapacity();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet; 695 typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
785 explicit UnorderedHashSet(RawArray* data) 696 explicit UnorderedHashSet(RawArray* data)
786 : BaseSet(Thread::Current()->zone(), data) { 697 : BaseSet(Thread::Current()->zone(), data) {
787 ASSERT(data != Array::null()); 698 ASSERT(data != Array::null());
788 } 699 }
789 UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} 700 UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
790 UnorderedHashSet(Object* key, Smi* value, Array* data) 701 UnorderedHashSet(Object* key, Smi* value, Array* data)
791 : BaseSet(key, value, data) {} 702 : BaseSet(key, value, data) {}
792 }; 703 };
793 704
794
795 template<typename KeyTraits>
796 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > {
797 public:
798 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet;
799 explicit EnumIndexHashSet(RawArray* data)
800 : BaseSet(Thread::Current()->zone(), data) {}
801 EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
802 EnumIndexHashSet(Object* key, Smi* value, Array* data)
803 : BaseSet(key, value, data) {}
804 };
805
806 } // namespace dart 705 } // namespace dart
807 706
808 #endif // VM_HASH_TABLE_H_ 707 #endif // VM_HASH_TABLE_H_
OLDNEW
« no previous file with comments | « runtime/vm/hash_map_test.cc ('k') | runtime/vm/hash_table_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698