Lines 32-37
import java.util.concurrent.ExecutionException;
Link Here
|
32 |
import java.util.concurrent.ExecutorService; |
32 |
import java.util.concurrent.ExecutorService; |
33 |
import java.util.concurrent.Executors; |
33 |
import java.util.concurrent.Executors; |
34 |
import java.util.concurrent.Future; |
34 |
import java.util.concurrent.Future; |
|
|
35 |
import java.util.concurrent.RecursiveAction; |
35 |
import java.util.concurrent.TimeUnit; |
36 |
import java.util.concurrent.TimeUnit; |
36 |
import java.util.function.Supplier; |
37 |
import java.util.function.Supplier; |
37 |
|
38 |
|
Lines 82-116
public abstract class IndexWriter
Link Here
|
82 |
|
83 |
|
83 |
public static class Identifier implements IIndexReader.IOne2LongIndex |
84 |
public static class Identifier implements IIndexReader.IOne2LongIndex |
84 |
{ |
85 |
{ |
85 |
long[] identifiers; |
86 |
private static final int SUBARRAY_SIZE = 4 * 1024 * 1024; // 8 bytes, 32MB chunks |
|
|
87 |
private static final int SUBARRAY_SHIFT = 22; |
88 |
private static final int SUBARRAY_MASK = 0b00111111_11111111_11111111; |
89 |
long[][] identifiers = new long[][] { new long[SUBARRAY_SIZE] }; |
86 |
int size; |
90 |
int size; |
87 |
|
91 |
|
88 |
public void add(long id) |
92 |
int findSubarrayForIndex(int index) |
89 |
{ |
93 |
{ |
90 |
if (identifiers == null) |
94 |
int array = index >> SUBARRAY_SHIFT; |
|
|
95 |
if (array >= identifiers.length) |
91 |
{ |
96 |
{ |
92 |
identifiers = new long[10000]; |
97 |
long[][] newIdentifiers = new long[identifiers.length * 2][]; |
93 |
size = 0; |
98 |
System.arraycopy(identifiers, 0, newIdentifiers, 0, identifiers.length); |
|
|
99 |
identifiers = newIdentifiers; |
94 |
} |
100 |
} |
95 |
|
101 |
if (identifiers[array] == null) |
96 |
if (size + 1 > identifiers.length) |
|
|
97 |
{ |
102 |
{ |
98 |
int minCapacity = size + 1; |
103 |
identifiers[array] = new long[SUBARRAY_SIZE]; |
99 |
int newCapacity = newCapacity(identifiers.length, minCapacity); |
104 |
long totalBytes = 0; |
100 |
if (newCapacity < minCapacity) |
105 |
for (long[] subarray : identifiers) |
101 |
{ |
106 |
{ |
102 |
// Avoid strange exceptions later |
107 |
if (subarray == null) |
103 |
throw new OutOfMemoryError(MessageUtil.format(Messages.IndexWriter_Error_ArrayLength, minCapacity, newCapacity)); |
108 |
continue; |
|
|
109 |
totalBytes += subarray.length * 8L; |
104 |
} |
110 |
} |
105 |
identifiers = copyOf(identifiers, newCapacity); |
|
|
106 |
} |
111 |
} |
|
|
112 |
return array; |
113 |
} |
107 |
|
114 |
|
108 |
identifiers[size++] = id; |
115 |
int findIndexIntoSubarray(int index) |
|
|
116 |
{ |
117 |
return index & SUBARRAY_MASK; |
118 |
} |
119 |
|
120 |
public void add(long id) |
121 |
{ |
122 |
int sub = findSubarrayForIndex(size); |
123 |
int idx = findIndexIntoSubarray(size); |
124 |
identifiers[sub][idx] = id; |
125 |
size++; |
126 |
} |
127 |
|
128 |
void set(int index, long id) |
129 |
{ |
130 |
int sub = findSubarrayForIndex(index); |
131 |
int idx = findIndexIntoSubarray(index); |
132 |
identifiers[sub][idx] = id; |
109 |
} |
133 |
} |
110 |
|
134 |
|
111 |
public void sort() |
135 |
public void sort() |
112 |
{ |
136 |
{ |
113 |
Arrays.parallelSort(identifiers, 0, size); |
137 |
new IdentifierSortTask(0, size - 1).invoke(); |
|
|
138 |
} |
139 |
|
140 |
class IdentifierSortTask extends RecursiveAction |
141 |
{ |
142 |
final int low, high; |
143 |
|
144 |
public IdentifierSortTask(final int low, final int high) |
145 |
{ |
146 |
this.low = low; |
147 |
this.high = high; |
148 |
} |
149 |
|
150 |
// adapted from: |
151 |
// https://www.vogella.com/tutorials/JavaAlgorithmsQuicksort/article.html |
152 |
// Copyright © 2012-2019 vogella GmbH. Free use of the software examples is |
153 |
// granted under the terms of the Eclipse Public |
154 |
// License 2.0. This tutorial is published under the Creative Commons |
155 |
// Attribution-NonCommercial-ShareAlike 3.0 Germany license. |
156 |
|
157 |
public void compute() |
158 |
{ |
159 |
// index range could be already met |
160 |
if (low >= high) |
161 |
{ return; } |
162 |
|
163 |
// Compute direct, defer to JDK sort as soon as possible |
164 |
if (findSubarrayForIndex(low) == findSubarrayForIndex(high)) |
165 |
{ |
166 |
Arrays.sort(identifiers[findSubarrayForIndex(low)], findIndexIntoSubarray(low), |
167 |
findIndexIntoSubarray(high) + 1); |
168 |
return; |
169 |
} |
170 |
|
171 |
int i = low, j = high; |
172 |
// Get the pivot element from the middle of the list |
173 |
long pivot = Identifier.this.get(low + (high - low) / 2); |
174 |
|
175 |
// Divide into two lists |
176 |
while (i <= j) |
177 |
{ |
178 |
// If the current value from the left list is smaller than the pivot |
179 |
// element then get the next element from the left list |
180 |
while (Identifier.this.get(i) < pivot) |
181 |
{ |
182 |
i++; |
183 |
} |
184 |
// If the current value from the right list is larger than the pivot |
185 |
// element then get the next element from the right list |
186 |
while (Identifier.this.get(j) > pivot) |
187 |
{ |
188 |
j--; |
189 |
} |
190 |
|
191 |
// If we have found a value in the left list which is larger than |
192 |
// the pivot element and if we have found a value in the right list |
193 |
// which is smaller than the pivot element then we exchange the |
194 |
// values. |
195 |
// As we are done we can increase i and j |
196 |
if (i <= j) |
197 |
{ |
198 |
exchange(i, j); |
199 |
i++; |
200 |
j--; |
201 |
} |
202 |
} |
203 |
// Recursion |
204 |
invokeAll(new IdentifierSortTask(low, j), new IdentifierSortTask(i, high)); |
205 |
} |
206 |
|
207 |
void exchange(int i, int j) |
208 |
{ |
209 |
long temp = Identifier.this.get(i); |
210 |
set(i, Identifier.this.get(j)); |
211 |
set(j, temp); |
212 |
} |
114 |
} |
213 |
} |
115 |
|
214 |
|
116 |
public int size() |
215 |
public int size() |
Lines 123-129
public abstract class IndexWriter
Link Here
|
123 |
if (index < 0 || index >= size) |
222 |
if (index < 0 || index >= size) |
124 |
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); //$NON-NLS-1$//$NON-NLS-2$ |
223 |
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size); //$NON-NLS-1$//$NON-NLS-2$ |
125 |
|
224 |
|
126 |
return identifiers[index]; |
225 |
return identifiers[findSubarrayForIndex(index)][findIndexIntoSubarray(index)]; |
127 |
} |
226 |
} |
128 |
|
227 |
|
129 |
public int reverse(long val) |
228 |
public int reverse(long val) |
Lines 165-171
public abstract class IndexWriter
Link Here
|
165 |
|
264 |
|
166 |
public long next() |
265 |
public long next() |
167 |
{ |
266 |
{ |
168 |
return identifiers[index++]; |
267 |
return get(index++); |
169 |
} |
268 |
} |
170 |
|
269 |
|
171 |
}; |
270 |
}; |