Skip to content

Commit 4509a1d

Browse files
authored
Attribute provides means to cache hashcode and sizeInBytes computation (#2986)
Most implementations of Attribute now cache the computation for hashcode and computation. Fix bug in JexlASTHelper's deconstructIdentifier method that caused a new String to be built, even when not necessary.
1 parent f8ae81a commit 4509a1d

File tree

13 files changed

+349
-77
lines changed

13 files changed

+349
-77
lines changed

warehouse/query-core/src/main/java/datawave/query/attributes/Attribute.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public abstract class Attribute<T extends Comparable<T>> implements WritableComp
3737
protected boolean toKeep = true; // a flag denoting whether this attribute is to be kept in the returned results (transient or not)
3838
protected boolean fromIndex = true; // Assume attributes are from the index unless specified otherwise.
3939

40+
// cache computation to avoid repeated calculation
41+
protected int hashcode = Integer.MIN_VALUE;
42+
protected long sizeInBytes = Long.MIN_VALUE;
43+
4044
public Attribute() {}
4145

4246
public Attribute(Key metadata, boolean toKeep) {
@@ -244,6 +248,7 @@ public boolean equals(Object o) {
244248

245249
@Override
246250
public int hashCode() {
251+
// Note: implementations of Attribute should cache the result of this operation
247252
HashCodeBuilder hcb = new HashCodeBuilder(145, 11);
248253
hcb.append(this.isMetadataSet());
249254
if (isMetadataSet()) {
@@ -285,15 +290,17 @@ public long sizeInBytes() {
285290
// 8 for the object overhead
286291
// 4 for the key reference
287292
// 1 for the keep boolean
288-
// all rounded up to the nearest multiple of 8 to make 16 out of 13 bytes
293+
// 4 for the hashcode reference
294+
// 8 for the sizeInBytes references
295+
// all rounded up to the nearest multiple of 8 to make 32 out of 25 bytes
289296
size += getMetadataSizeInBytes();
290297
return size;
291298
}
292299

293300
// for use by subclasses to estimate size
294301
protected long sizeInBytes(long extra) {
295-
return roundUp(extra + 13) + getMetadataSizeInBytes();
296-
// 13 is the base size in bytes (see sizeInBytes(), unrounded and without metadata)
302+
return roundUp(extra + 25) + getMetadataSizeInBytes();
303+
// 25 is the base size in bytes (see sizeInBytes(), unrounded and without metadata)
297304
}
298305

299306
// a helper method to return the size of a string

warehouse/query-core/src/main/java/datawave/query/attributes/Attributes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ public long sizeInBytes() {
9090
}
9191

9292
public void add(Attribute<? extends Comparable<?>> attr) {
93-
if (!this.attributes.contains(attr)) {
94-
this.attributes.add(attr);
93+
boolean updated = this.attributes.add(attr);
94+
if (updated) {
9595
this._count += attr.size();
9696
if (trackSizes) {
9797
this._bytes += attr.sizeInBytes() + 24 + 24;

warehouse/query-core/src/main/java/datawave/query/attributes/Content.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ public Content(String content, Key docKey, boolean toKeep, Attribute<?> source)
4343

4444
@Override
4545
public long sizeInBytes() {
46-
return sizeInBytes(content) + super.sizeInBytes(4);
47-
// 4 for string reference
46+
if (sizeInBytes == Long.MIN_VALUE) {
47+
// 4 for string reference
48+
sizeInBytes = sizeInBytes(content) + super.sizeInBytes(4) + 4;
49+
}
50+
return sizeInBytes;
4851
}
4952

5053
public String getContent() {
@@ -119,10 +122,15 @@ public boolean equals(Object o) {
119122

120123
@Override
121124
public int hashCode() {
122-
HashCodeBuilder hcb = new HashCodeBuilder(2099, 2129);
123-
hcb.append(content).append(super.hashCode());
124-
125-
return hcb.toHashCode();
125+
if (hashcode == Integer.MIN_VALUE) {
126+
// @formatter:off
127+
hashcode = new HashCodeBuilder(2099, 2129)
128+
.append(content)
129+
.append(super.hashCode())
130+
.toHashCode();
131+
// @formatter:off
132+
}
133+
return hashcode;
126134
}
127135

128136
@Override

warehouse/query-core/src/main/java/datawave/query/attributes/Geometry.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@ public Geometry(org.locationtech.jts.geom.Geometry geometry, Key docKey, boolean
4747

4848
@Override
4949
public long sizeInBytes() {
50-
return ObjectSizeOf.Sizer.getObjectSize(geometry) + super.sizeInBytes(4);
51-
// 4 for geometry reference
50+
if (sizeInBytes == Long.MIN_VALUE) {
51+
// 4 for geometry reference
52+
sizeInBytes = ObjectSizeOf.Sizer.getObjectSize(geometry) + super.sizeInBytes(4);
53+
}
54+
return sizeInBytes;
5255
}
5356

5457
private byte[] write() {
@@ -128,10 +131,15 @@ public boolean equals(Object o) {
128131

129132
@Override
130133
public int hashCode() {
131-
HashCodeBuilder hcb = new HashCodeBuilder(163, 157);
132-
hcb.append(super.hashCode()).append(geometry);
133-
134-
return hcb.toHashCode();
134+
if (hashcode == Integer.MIN_VALUE) {
135+
// @formatter:off
136+
hashcode = new HashCodeBuilder(163, 157)
137+
.append(super.hashCode())
138+
.append(geometry)
139+
.toHashCode();
140+
// @formatter:on
141+
}
142+
return hashcode;
135143
}
136144

137145
@Override

warehouse/query-core/src/main/java/datawave/query/attributes/IpAddress.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ public IpAddress(String ipAddress, Key docKey, boolean toKeep) {
3636

3737
@Override
3838
public long sizeInBytes() {
39-
return sizeInBytes(value.toString()) + sizeInBytes(normalizedValue) + super.sizeInBytes(8);
40-
// 8 for string references
39+
if (sizeInBytes == Long.MIN_VALUE) {
40+
// 8 for string references
41+
sizeInBytes = sizeInBytes(value.toString()) + sizeInBytes(normalizedValue) + super.sizeInBytes(8);
42+
}
43+
return sizeInBytes;
4144
}
4245

4346
protected void validate() {
@@ -103,10 +106,15 @@ public boolean equals(Object o) {
103106

104107
@Override
105108
public int hashCode() {
106-
HashCodeBuilder hcb = new HashCodeBuilder(163, 157);
107-
hcb.append(super.hashCode()).append(this.value);
108-
109-
return hcb.toHashCode();
109+
if (hashcode == Integer.MIN_VALUE) {
110+
// @formatter:off
111+
hashcode = new HashCodeBuilder(163, 157)
112+
.append(super.hashCode())
113+
.append(this.value)
114+
.toHashCode();
115+
// @formatter:on
116+
}
117+
return hashcode;
110118
}
111119

112120
@Override

warehouse/query-core/src/main/java/datawave/query/attributes/Numeric.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ public Numeric(Number value, Key docKey, boolean toKeep) {
4949

5050
@Override
5151
public long sizeInBytes() {
52-
return 20 + sizeInBytes(normalizedValue) + super.sizeInBytes(8);
53-
// 20 is for a basic int Number
54-
// 8 for string references
52+
if (sizeInBytes == Long.MIN_VALUE) {
53+
// 20 is for a basic int Number
54+
// 8 for string references
55+
sizeInBytes = 20 + sizeInBytes(normalizedValue) + super.sizeInBytes(8);
56+
}
57+
return sizeInBytes;
5558
}
5659

5760
/**
@@ -153,10 +156,15 @@ public boolean equals(Object o) {
153156

154157
@Override
155158
public int hashCode() {
156-
HashCodeBuilder hcb = new HashCodeBuilder(113, 127);
157-
hcb.append(super.hashCode()).append(value);
158-
159-
return hcb.toHashCode();
159+
if (hashcode == Integer.MIN_VALUE) {
160+
// @formatter:off
161+
hashcode = new HashCodeBuilder(113, 127)
162+
.append(super.hashCode())
163+
.append(value)
164+
.toHashCode();
165+
// @formatter:on
166+
}
167+
return hashcode;
160168
}
161169

162170
@Override

warehouse/query-core/src/main/java/datawave/query/attributes/PreNormalizedAttribute.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ public PreNormalizedAttribute(String value, Key docKey, boolean toKeep) {
4040

4141
@Override
4242
public long sizeInBytes() {
43-
return sizeInBytes(value) + super.sizeInBytes(4);
44-
// 4 for string reference
43+
if (sizeInBytes == Long.MIN_VALUE) {
44+
// 4 bytes for string reference
45+
sizeInBytes = sizeInBytes(value) + super.sizeInBytes(4);
46+
}
47+
return sizeInBytes;
4548
}
4649

4750
@Override
@@ -59,10 +62,15 @@ public boolean equals(Object o) {
5962

6063
@Override
6164
public int hashCode() {
62-
HashCodeBuilder hcb = new HashCodeBuilder(2141, 2137);
63-
hcb.append(super.hashCode()).append(this.getData());
64-
65-
return hcb.toHashCode();
65+
if (hashcode == Integer.MIN_VALUE) {
66+
// @formatter:off
67+
hashcode = new HashCodeBuilder(2141, 2137)
68+
.append(super.hashCode())
69+
.append(this.getData())
70+
.toHashCode();
71+
// @formatter:on
72+
}
73+
return hashcode;
6674
}
6775

6876
@Override

warehouse/query-core/src/main/java/datawave/query/attributes/TypeAttribute.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,11 @@ public TypeAttribute(Type<T> datawaveType, Key docKey, boolean toKeep) {
5151

5252
@Override
5353
public long sizeInBytes() {
54-
long size = ObjectSizeOf.Sizer.getObjectSize(datawaveType) + super.sizeInBytes(4) + 2L;
55-
if (delegateString != null) {
56-
size += (2L + delegateString.length());
54+
if (sizeInBytes == Long.MAX_VALUE) {
55+
// 4 for datawaveType reference
56+
sizeInBytes = ObjectSizeOf.Sizer.getObjectSize(datawaveType) + super.sizeInBytes(4);
5757
}
58-
return size;
59-
// 4 for datawaveType reference
58+
return sizeInBytes;
6059
}
6160

6261
public Type<T> getType() {
@@ -135,15 +134,15 @@ public boolean equals(Object o) {
135134

136135
@Override
137136
public int hashCode() {
138-
if (this.hashCode == Integer.MIN_VALUE) {
137+
if (hashcode == Integer.MIN_VALUE) {
139138
// @formatter:off
140-
this.hashCode = new HashCodeBuilder(2099, 2129)
139+
hashcode = new HashCodeBuilder(2099, 2129)
141140
.append(datawaveType.getDelegateAsString())
142141
.append(super.hashCode())
143142
.toHashCode();
144143
// @formatter:on
145144
}
146-
return hashCode;
145+
return hashcode;
147146
}
148147

149148
@Override

warehouse/query-core/src/main/java/datawave/query/common/grouping/GroupingAttribute.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ private boolean isMetadataRowEqual(Attribute<?> other) {
5858
*/
5959
@Override
6060
public int hashCode() {
61-
return new HashCodeBuilder(2099, 2129).append(getType().getDelegateAsString()).toHashCode();
61+
if (hashcode == Integer.MIN_VALUE) {
62+
// @formatter:off
63+
hashcode = new HashCodeBuilder(2099, 2129)
64+
.append(getType().getDelegateAsString())
65+
.toHashCode();
66+
// @formatter:on
67+
}
68+
return hashcode;
69+
}
70+
71+
@Override
72+
public long sizeInBytes() {
73+
if (sizeInBytes == Long.MIN_VALUE) {
74+
sizeInBytes = super.sizeInBytes();
75+
}
76+
return sizeInBytes;
6277
}
6378
}

warehouse/query-core/src/main/java/datawave/query/jexl/JexlASTHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ public static String deconstructIdentifier(String fieldName, boolean includeGrou
699699
}
700700
}
701701

702-
if (startIndex != 0 || stopLength != -1) {
702+
if (startIndex != 0 || stopLength != fieldName.length()) {
703703
fieldName = new String(fieldName.getBytes(), startIndex, stopLength);
704704
}
705705
}

0 commit comments

Comments
 (0)