Skip to content

Commit eb07a29

Browse files
committed
Specialize viewer storage hot loops
1 parent 9dd03d4 commit eb07a29

1 file changed

Lines changed: 75 additions & 65 deletions

File tree

common/src/main/java/com/loohp/interactionvisualizer/entities/DroppedItemSpatialIndex.java

Lines changed: 75 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static final class ViewerIndex {
109109
void addViewer(UUID worldId, double x, double y, double z) {
110110
if (singleWorldViewers == null) {
111111
singleWorldId = worldId;
112-
singleWorldViewers = new WorldViewerBucket(expectedViewers, pointStorage);
112+
singleWorldViewers = createBucket(expectedViewers);
113113
singleWorldViewers.add(x, y, z);
114114
return;
115115
}
@@ -121,7 +121,7 @@ void addViewer(UUID worldId, double x, double y, double z) {
121121
viewersByWorld = new HashMap<>();
122122
viewersByWorld.put(singleWorldId, singleWorldViewers);
123123
}
124-
viewersByWorld.computeIfAbsent(worldId, ignored -> new WorldViewerBucket(0, pointStorage)).add(x, y, z);
124+
viewersByWorld.computeIfAbsent(worldId, ignored -> createBucket(0)).add(x, y, z);
125125
}
126126

127127
boolean isEmpty() {
@@ -132,6 +132,12 @@ boolean usesPointStorage() {
132132
return pointStorage;
133133
}
134134

135+
private WorldViewerBucket createBucket(int initialCapacity) {
136+
return pointStorage
137+
? new PointWorldViewerBucket(initialCapacity)
138+
: new PrimitiveWorldViewerBucket(initialCapacity);
139+
}
140+
135141
boolean hasViewerWithin(UUID worldId, double x, double y, double z, double range) {
136142
if (range < 0.0D) {
137143
return false;
@@ -142,49 +148,32 @@ boolean hasViewerWithin(UUID worldId, double x, double y, double z, double range
142148
return viewers != null && viewers.hasViewerWithin(x, y, z, range * range);
143149
}
144150

145-
private static final class WorldViewerBucket {
151+
private abstract static class WorldViewerBucket {
152+
153+
abstract void add(double x, double y, double z);
154+
155+
abstract boolean hasViewerWithin(double x, double y, double z, double rangeSquared);
156+
}
157+
158+
private static final class PrimitiveWorldViewerBucket extends WorldViewerBucket {
146159

147-
private static final int INITIAL_CAPACITY = 8;
148-
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
149160
private static final double[] EMPTY = new double[0];
150-
private static final Point[] EMPTY_POINTS = new Point[0];
151161

152162
private double[] xCoordinates = EMPTY;
153163
private double[] yCoordinates = EMPTY;
154164
private double[] zCoordinates = EMPTY;
155-
private Point[] points = EMPTY_POINTS;
156-
private final boolean pointStorage;
157165
private int size;
158166

159-
private WorldViewerBucket(int initialCapacity, boolean pointStorage) {
160-
this.pointStorage = pointStorage;
167+
private PrimitiveWorldViewerBucket(int initialCapacity) {
161168
if (initialCapacity > 0) {
162-
if (pointStorage) {
163-
points = new Point[initialCapacity];
164-
} else {
165-
xCoordinates = new double[initialCapacity];
166-
yCoordinates = new double[initialCapacity];
167-
zCoordinates = new double[initialCapacity];
168-
}
169+
xCoordinates = new double[initialCapacity];
170+
yCoordinates = new double[initialCapacity];
171+
zCoordinates = new double[initialCapacity];
169172
}
170173
}
171174

172-
private void add(double x, double y, double z) {
173-
if (pointStorage) {
174-
addPoint(x, y, z);
175-
return;
176-
}
177-
addCoordinates(x, y, z);
178-
}
179-
180-
private void addPoint(double x, double y, double z) {
181-
if (size == points.length) {
182-
points = grow(points, grownCapacity(size));
183-
}
184-
points[size++] = new Point(x, y, z);
185-
}
186-
187-
private void addCoordinates(double x, double y, double z) {
175+
@Override
176+
void add(double x, double y, double z) {
188177
if (size == xCoordinates.length) {
189178
int capacity = grownCapacity(size);
190179
xCoordinates = grow(xCoordinates, capacity);
@@ -197,57 +186,78 @@ private void addCoordinates(double x, double y, double z) {
197186
size++;
198187
}
199188

200-
private boolean hasViewerWithin(double x, double y, double z, double rangeSquared) {
201-
return pointStorage
202-
? hasPointWithin(x, y, z, rangeSquared)
203-
: hasCoordinatesWithin(x, y, z, rangeSquared);
204-
}
205-
206-
private boolean hasPointWithin(double x, double y, double z, double rangeSquared) {
189+
@Override
190+
boolean hasViewerWithin(double x, double y, double z, double rangeSquared) {
207191
for (int index = 0; index < size; index++) {
208-
Point point = points[index];
209-
double deltaX = point.x() - x;
210-
double deltaY = point.y() - y;
211-
double deltaZ = point.z() - z;
192+
double deltaX = xCoordinates[index] - x;
193+
double deltaY = yCoordinates[index] - y;
194+
double deltaZ = zCoordinates[index] - z;
212195
if (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ <= rangeSquared) {
213196
return true;
214197
}
215198
}
216199
return false;
217200
}
201+
}
202+
203+
private static final class PointWorldViewerBucket extends WorldViewerBucket {
204+
205+
private static final Point[] EMPTY = new Point[0];
206+
207+
private Point[] points = EMPTY;
208+
private int size;
209+
210+
private PointWorldViewerBucket(int initialCapacity) {
211+
if (initialCapacity > 0) {
212+
points = new Point[initialCapacity];
213+
}
214+
}
218215

219-
private boolean hasCoordinatesWithin(double x, double y, double z, double rangeSquared) {
216+
@Override
217+
void add(double x, double y, double z) {
218+
if (size == points.length) {
219+
points = grow(points, grownCapacity(size));
220+
}
221+
points[size++] = new Point(x, y, z);
222+
}
223+
224+
@Override
225+
boolean hasViewerWithin(double x, double y, double z, double rangeSquared) {
220226
for (int index = 0; index < size; index++) {
221-
double deltaX = xCoordinates[index] - x;
222-
double deltaY = yCoordinates[index] - y;
223-
double deltaZ = zCoordinates[index] - z;
227+
Point point = points[index];
228+
double deltaX = point.x() - x;
229+
double deltaY = point.y() - y;
230+
double deltaZ = point.z() - z;
224231
if (deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ <= rangeSquared) {
225232
return true;
226233
}
227234
}
228235
return false;
229236
}
237+
}
230238

231-
private static double[] grow(double[] source, int capacity) {
232-
double[] expanded = new double[capacity];
233-
System.arraycopy(source, 0, expanded, 0, source.length);
234-
return expanded;
235-
}
239+
private static final int INITIAL_BUCKET_CAPACITY = 8;
240+
private static final int MAX_BUCKET_ARRAY_SIZE = Integer.MAX_VALUE - 8;
236241

237-
private static Point[] grow(Point[] source, int capacity) {
238-
Point[] expanded = new Point[capacity];
239-
System.arraycopy(source, 0, expanded, 0, source.length);
240-
return expanded;
242+
private static int grownCapacity(int size) {
243+
if (size >= MAX_BUCKET_ARRAY_SIZE) {
244+
throw new OutOfMemoryError("Too many viewers");
241245
}
246+
return size > MAX_BUCKET_ARRAY_SIZE / 2
247+
? MAX_BUCKET_ARRAY_SIZE
248+
: Math.max(INITIAL_BUCKET_CAPACITY, size << 1);
249+
}
242250

243-
private static int grownCapacity(int size) {
244-
if (size >= MAX_ARRAY_SIZE) {
245-
throw new OutOfMemoryError("Too many viewers");
246-
}
247-
return size > MAX_ARRAY_SIZE / 2
248-
? MAX_ARRAY_SIZE
249-
: Math.max(INITIAL_CAPACITY, size << 1);
250-
}
251+
private static double[] grow(double[] source, int capacity) {
252+
double[] expanded = new double[capacity];
253+
System.arraycopy(source, 0, expanded, 0, source.length);
254+
return expanded;
255+
}
256+
257+
private static Point[] grow(Point[] source, int capacity) {
258+
Point[] expanded = new Point[capacity];
259+
System.arraycopy(source, 0, expanded, 0, source.length);
260+
return expanded;
251261
}
252262
}
253263

0 commit comments

Comments
 (0)