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

Side by Side Diff: dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/index/file/IntToIntSetMap.java

Issue 371913004: Version 1.5.6 (Closed) Base URL: http://dart.googlecode.com/svn/branches/1.5/
Patch Set: Created 6 years, 5 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 package com.google.dart.engine.internal.index.file;
2
3 import org.apache.commons.lang3.ArrayUtils;
4
5 import java.util.Arrays;
6
7 /**
8 * A table mapping {@code int} keys to sets of {@code int}s.
9 *
10 * @coverage dart.engine.index
11 */
12 public class IntToIntSetMap {
13 private static class Entry {
14 private final int key;
15 private int[] value;
16 Entry next;
17
18 public Entry(int key, int[] value, Entry next) {
19 this.key = key;
20 this.value = value;
21 this.next = next;
22 }
23 }
24
25 private final float loadFactor;
26 private int capacity;
27 private int threshold;
28 private int size;
29 private int[] keys;
30 private int[][] values;
31 private Entry[] entries;
32
33 public IntToIntSetMap(int initialCapacity, float loadFactor) {
34 this.loadFactor = loadFactor;
35 capacity = initialCapacity;
36 threshold = (int) (capacity * loadFactor);
37 size = 0;
38 keys = new int[capacity];
39 values = new int[capacity][];
40 entries = new Entry[capacity];
41 Arrays.fill(keys, -1);
42 }
43
44 /**
45 * Adds the given value into the set associated with the given key in this map .
46 */
47 public void add(int key, int value) {
48 if (key < 0) {
49 throw new IllegalArgumentException("Key must be a positive integer or null , but " + key
50 + " is given.");
51 }
52 // rehash
53 if (size >= threshold) {
54 rehash();
55 }
56 // prepare hash
57 int hash = hash(key);
58 int index = hash % capacity;
59 // try "intKeys"
60 Entry entry = entries[index];
61 if (entry == null) {
62 int intKey = keys[index];
63 if (intKey == -1) {
64 keys[index] = key;
65 values[index] = addValue(values[index], value);
66 size++;
67 return;
68 }
69 if (intKey == key) {
70 values[index] = addValue(values[index], value);
71 return;
72 }
73 // collision, create new Entry
74 Entry existingEntry = new Entry(intKey, values[index], null);
75 entries[index] = new Entry(key, addValue(null, value), existingEntry);
76 keys[index] = -1;
77 values[index] = null;
78 size++;
79 return;
80 }
81 // check existing entries
82 while (entry != null) {
83 if (entry.key == key) {
84 entry.value = addValue(entry.value, value);
85 return;
86 }
87 entry = entry.next;
88 }
89 // add new Entry
90 entries[index] = new Entry(key, addValue(null, value), entries[index]);
91 size++;
92 }
93
94 /**
95 * Removes all of the mappings from this map.
96 */
97 public void clear() {
98 size = 0;
99 Arrays.fill(keys, -1);
100 Arrays.fill(values, null);
101 Arrays.fill(entries, null);
102 }
103
104 /**
105 * Returns the values to which the specified key is mapped, or an empty {@code int[]} array if
106 * this map contains no mapping for the key.
107 *
108 * @param key the key whose associated value is to be returned
109 * @return the values associated with {@code key}, or an empty {@code int[]} a rray if there is no
110 * mapping for {@code key}
111 */
112 public int[] get(int key) {
113 int hash = hash(key);
114 int index = hash % capacity;
115 // try "keys"
116 {
117 int intKey = keys[index];
118 if (intKey == key) {
119 return values[index];
120 }
121 }
122 // try "entries"
123 {
124 Entry entry = entries[index];
125 while (entry != null) {
126 if (entry.key == key) {
127 return entry.value;
128 }
129 entry = entry.next;
130 }
131 }
132 return ArrayUtils.EMPTY_INT_ARRAY;
133 }
134
135 /**
136 * Returns the number of key-value mappings in this map.
137 */
138 public int size() {
139 return size;
140 }
141
142 private int[] addValue(int[] set, int value) {
143 if (set == null) {
144 return new int[] {value};
145 }
146 if (ArrayUtils.indexOf(set, value) != -1) {
147 return set;
148 }
149 return ArrayUtils.add(set, value);
150 }
151
152 private void addValues(int key, int[] values) {
153 for (int value : values) {
154 add(key, value);
155 }
156 }
157
158 private int hash(int h) {
159 h ^= (h >>> 20) ^ (h >>> 12);
160 h = h ^ (h >>> 7) ^ (h >>> 4);
161 return h & 0x7FFFFFFF;
162 }
163
164 private void rehash() {
165 IntToIntSetMap newMap = new IntToIntSetMap(capacity * 2 + 1, loadFactor);
166 // put values
167 for (int i = 0; i < keys.length; i++) {
168 int key = keys[i];
169 if (key != -1) {
170 newMap.addValues(key, values[i]);
171 }
172 }
173 for (int i = 0; i < entries.length; i++) {
174 Entry entry = entries[i];
175 while (entry != null) {
176 newMap.addValues(entry.key, entry.value);
177 entry = entry.next;
178 }
179 }
180 // copy data
181 capacity = newMap.capacity;
182 threshold = newMap.threshold;
183 keys = newMap.keys;
184 values = newMap.values;
185 entries = newMap.entries;
186 }
187 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698