Skip to content

Commit 9c80116

Browse files
authored
Merge pull request #669 from apache/ffm_phase2
FFM transition: Phase 2: HLL
2 parents 882eb45 + 587f2cd commit 9c80116

81 files changed

Lines changed: 3423 additions & 3348 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pom.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ under the License.
9393
<testng.check-cpp-historical-files>check_cpp_historical_files</testng.check-cpp-historical-files>
9494

9595
<!-- System-wide properties -->
96-
<maven.version>3.6.3</maven.version>
96+
<maven.version>3.9.10</maven.version>
9797
<java.version>24</java.version>
9898
<jvm-arguments></jvm-arguments>
9999
<maven.compiler.source>${java.version}</maven.compiler.source>
@@ -107,16 +107,16 @@ under the License.
107107

108108
<!-- org.apache.maven plugins -->
109109
<maven-assembly-plugin.version>3.7.1</maven-assembly-plugin.version>
110-
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
111-
<maven-deploy-plugin.version>3.1.3</maven-deploy-plugin.version>
112-
<maven-enforcer-plugin.version>3.5.0</maven-enforcer-plugin.version>
113-
<maven-gpg-plugin.version>3.2.7</maven-gpg-plugin.version>
110+
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
111+
<maven-deploy-plugin.version>3.1.4</maven-deploy-plugin.version>
112+
<maven-enforcer-plugin.version>3.6.0</maven-enforcer-plugin.version>
113+
<maven-gpg-plugin.version>3.2.8</maven-gpg-plugin.version>
114114
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
115115
<maven-javadoc-plugin.version>3.11.2</maven-javadoc-plugin.version>
116116
<maven-release-plugin.version>3.1.1</maven-release-plugin.version>
117117
<maven-source-plugin.version>3.3.1</maven-source-plugin.version>
118118
<!-- for surefire, failsafe and surefire-report: -->
119-
<maven-surefire-failsafe-plugins.version>3.5.2</maven-surefire-failsafe-plugins.version>
119+
<maven-surefire-failsafe-plugins.version>3.5.3</maven-surefire-failsafe-plugins.version>
120120
<maven-toolchains-plugin.version>3.2.0</maven-toolchains-plugin.version>
121121
<!-- com.github plugins -->
122122
<git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>

src/main/java/org/apache/datasketches/common/MemorySegmentStatus.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.apache.datasketches.common;
2121

2222
import java.lang.foreign.MemorySegment;
23+
import java.util.Optional;
2324

2425
/**
2526
* Methods for inquiring the status of a backing MemorySegment.
@@ -37,22 +38,41 @@ public interface MemorySegmentStatus {
3738
* Returns true if this object's internal data is backed by an off-heap (direct or native)) MemorySegment.
3839
* @return true if this object's internal data is backed by an off-heap (direct or native)) MemorySegment.
3940
*/
40-
boolean isDirect();
41+
boolean isOffHeap();
4142

4243
/**
43-
* Returns true if the backing MemorySegment of this object refers to the same MemorySegment of <i>that</i>.
44-
* They can either have the same off-heap memory location and size, or refer to the same on-heap array object.
44+
* Returns true if an internally referenced MemorySegment has the same backing resource as <i>that</i>,
45+
* or equivalently, if their two memory regions overlap. This applies to both on-heap and off-heap MemorySegments.
4546
*
46-
* <p>If both segment are off-heap, they both must have the same starting address and the same size.</p>
47+
* <p>This returns false if either segment is <i>null</i> or not alive.</p>
4748
*
48-
* <p>For on-heap segments, both segments must be based on or derived from the same array object and neither segment
49-
* can be read-only.</p>
50-
*
51-
* <p>Returns false if either argument is null;</p>
49+
* <p><b>Note:</b> If both segments are on-heap and not read-only, it can be determined if they were derived from
50+
* the same backing memory (array). However, this is not always possible off-heap. Because of this asymmetry, this definition
51+
* of "isSameResource" is confined to the existence of an overlap.</p>
5252
*
5353
* @param that The given MemorySegment.
54-
* @return true if the backing MemorySegment of this object hierarchy refers to the same MemorySegment of <i>that</i>.
54+
* @return true if an internally referenced MemorySegment has the same backing resource as <i>that</i>.
5555
*/
5656
boolean isSameResource(final MemorySegment that);
5757

58+
/**
59+
* Returns true if the two given MemorySegments have to the same backing resource, or equivalently,
60+
* if the two memory regions overlap. This applies to both on-heap and off-heap MemorySegments.
61+
*
62+
* <p>This returns false if either segment is <i>null</i> or not alive.</p>
63+
*
64+
* <p><b>Note:</b> If both segments are on-heap and not read-only, it can be determined if they were derived from
65+
* the same backing memory (array). However, this is not always possible off-heap. Because of this asymmetry, this definition
66+
* of "isSameResource" is confined to the existence of an overlap.</p>
67+
*
68+
* @param seg1 The first given MemorySegment
69+
* @param seg2 The second given MemorySegment
70+
* @return true if the two given MemorySegments have to the same backing resource.
71+
*/
72+
static boolean isSameResource(final MemorySegment seg1, final MemorySegment seg2) {
73+
if ((seg1 == null) || (seg2 == null) || !seg1.scope().isAlive() || !seg2.scope().isAlive()) { return false; }
74+
final Optional<MemorySegment> opt = seg1.asOverlappingSlice(seg2);
75+
return opt.isPresent();
76+
}
77+
5878
}

src/main/java/org/apache/datasketches/common/Util.java

Lines changed: 29 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ private Util() {}
101101
* @return an int extracted from a Little-Endian byte array.
102102
*/
103103
public static int bytesToInt(final byte[] arr) {
104-
return arr[3] << 24
105-
| (arr[2] & 0xff) << 16
106-
| (arr[1] & 0xff) << 8
107-
| arr[0] & 0xff;
104+
return (arr[3] << 24)
105+
| ((arr[2] & 0xff) << 16)
106+
| ((arr[1] & 0xff) << 8)
107+
| (arr[0] & 0xff);
108108
}
109109

110110
/**
@@ -113,14 +113,14 @@ public static int bytesToInt(final byte[] arr) {
113113
* @return a long extracted from a Little-Endian byte array.
114114
*/
115115
public static long bytesToLong(final byte[] arr) {
116-
return (long)arr[7] << 56
117-
| ((long)arr[6] & 0xff) << 48
118-
| ((long)arr[5] & 0xff) << 40
119-
| ((long)arr[4] & 0xff) << 32
120-
| ((long)arr[3] & 0xff) << 24
121-
| ((long)arr[2] & 0xff) << 16
122-
| ((long)arr[1] & 0xff) << 8
123-
| (long)arr[0] & 0xff;
116+
return ((long)arr[7] << 56)
117+
| (((long)arr[6] & 0xff) << 48)
118+
| (((long)arr[5] & 0xff) << 40)
119+
| (((long)arr[4] & 0xff) << 32)
120+
| (((long)arr[3] & 0xff) << 24)
121+
| (((long)arr[2] & 0xff) << 16)
122+
| (((long)arr[1] & 0xff) << 8)
123+
| ((long)arr[0] & 0xff);
124124
}
125125

126126
/**
@@ -159,7 +159,7 @@ public static byte[] longToBytes(final long v, final byte[] arr) {
159159

160160
static long[] convertToLongArray(final byte[] byteArr, final boolean littleEndian) {
161161
final int len = byteArr.length;
162-
final long[] longArr = new long[len / 8 + (len % 8 != 0 ? 1 : 0)];
162+
final long[] longArr = new long[(len / 8) + ((len % 8) != 0 ? 1 : 0)];
163163
int off = 0;
164164
int longArrIdx = 0;
165165
while (off < len) {
@@ -191,7 +191,7 @@ public static String longToHexBytes(final long v) {
191191
final long mask = 0XFFL;
192192
final StringBuilder sb = new StringBuilder();
193193
for (int i = 8; i-- > 0; ) {
194-
final String s = Long.toHexString(v >>> i * 8 & mask);
194+
final String s = Long.toHexString((v >>> (i * 8)) & mask);
195195
sb.append(zeroPad(s, 2)).append(" ");
196196
}
197197
return sb.toString();
@@ -211,7 +211,7 @@ public static String bytesToString(
211211
final int mask = signed ? 0XFFFFFFFF : 0XFF;
212212
final int arrLen = arr.length;
213213
if (littleEndian) {
214-
for (int i = 0; i < arrLen - 1; i++) {
214+
for (int i = 0; i < (arrLen - 1); i++) {
215215
sb.append(arr[i] & mask).append(sep);
216216
}
217217
sb.append(arr[arrLen - 1] & mask);
@@ -231,8 +231,8 @@ public static String bytesToString(
231231
*/
232232
public static String nanoSecToString(final long nS) {
233233
final long rem_nS = (long)(nS % 1000.0);
234-
final long rem_uS = (long)(nS / 1000.0 % 1000.0);
235-
final long rem_mS = (long)(nS / 1000000.0 % 1000.0);
234+
final long rem_uS = (long)((nS / 1000.0) % 1000.0);
235+
final long rem_mS = (long)((nS / 1000000.0) % 1000.0);
236236
final long sec = (long)(nS / 1000000000.0);
237237
final String nSstr = zeroPad(Long.toString(rem_nS), 3);
238238
final String uSstr = zeroPad(Long.toString(rem_uS), 3);
@@ -247,8 +247,8 @@ public static String nanoSecToString(final long nS) {
247247
*/
248248
public static String milliSecToString(final long mS) {
249249
final long rem_mS = (long)(mS % 1000.0);
250-
final long rem_sec = (long)(mS / 1000.0 % 60.0);
251-
final long rem_min = (long)(mS / 60000.0 % 60.0);
250+
final long rem_sec = (long)((mS / 1000.0) % 60.0);
251+
final long rem_min = (long)((mS / 60000.0) % 60.0);
252252
final long hr = (long)(mS / 3600000.0);
253253
final String mSstr = zeroPad(Long.toString(rem_mS), 3);
254254
final String secStr = zeroPad(Long.toString(rem_sec), 2);
@@ -296,7 +296,7 @@ public static String characterPad(final String s, final int fieldLength, final c
296296
* @param argName This name will be part of the error message if the check fails.
297297
*/
298298
public static void checkIfMultipleOf8AndGT0(final long v, final String argName) {
299-
if ((v & 0X7L) == 0L && v > 0L) {
299+
if (((v & 0X7L) == 0L) && (v > 0L)) {
300300
return;
301301
}
302302
throw new SketchesArgumentException("The value of the parameter \"" + argName
@@ -309,7 +309,7 @@ public static void checkIfMultipleOf8AndGT0(final long v, final String argName)
309309
* @return true if v is a multiple of 8 and greater than zero
310310
*/
311311
public static boolean isMultipleOf8AndGT0(final long v) {
312-
return (v & 0X7L) == 0L && v > 0L;
312+
return ((v & 0X7L) == 0L) && (v > 0L);
313313
}
314314

315315
//Powers of 2 or powers of base related
@@ -356,7 +356,7 @@ public static void checkIfPowerOf2(final long n, String argName) {
356356
public static int ceilingPowerOf2(final int n) {
357357
if (n <= 1) { return 1; }
358358
final int topIntPwrOf2 = 1 << 30;
359-
return n >= topIntPwrOf2 ? topIntPwrOf2 : Integer.highestOneBit(n - 1 << 1);
359+
return n >= topIntPwrOf2 ? topIntPwrOf2 : Integer.highestOneBit((n - 1) << 1);
360360
}
361361

362362
/**
@@ -377,7 +377,7 @@ public static int ceilingPowerOf2(final int n) {
377377
public static long ceilingPowerOf2(final long n) {
378378
if (n <= 1L) { return 1L; }
379379
final long topIntPwrOf2 = 1L << 62;
380-
return n >= topIntPwrOf2 ? topIntPwrOf2 : Long.highestOneBit(n - 1L << 1);
380+
return n >= topIntPwrOf2 ? topIntPwrOf2 : Long.highestOneBit((n - 1L) << 1);
381381
}
382382

383383
/**
@@ -430,8 +430,8 @@ public static long floorPowerOf2(final long n) {
430430
* @return the inverse integer power of 2: 1/(2^e) = 2^(-e)
431431
*/
432432
public static double invPow2(final int e) {
433-
assert (e | 1024 - e - 1) >= 0 : "e cannot be negative or greater than 1023: " + e;
434-
return Double.longBitsToDouble(1023L - e << 52);
433+
assert (e | (1024 - e - 1)) >= 0 : "e cannot be negative or greater than 1023: " + e;
434+
return Double.longBitsToDouble((1023L - e) << 52);
435435
}
436436

437437
/**
@@ -695,7 +695,7 @@ public static void checkBounds(final long reqOff, final long reqLen, final long
695695
* @param argName Used in the thrown exception.
696696
*/
697697
public static void checkProbability(final double p, final String argName) {
698-
if (p >= 0.0 && p <= 1.0) {
698+
if ((p >= 0.0) && (p <= 1.0)) {
699699
return;
700700
}
701701
throw new SketchesArgumentException("The value of the parameter \"" + argName
@@ -711,7 +711,7 @@ public static void checkProbability(final double p, final String argName) {
711711
* @return true if n1 &gt; n2.
712712
*/
713713
public static boolean isLessThanUnsigned(final long n1, final long n2) {
714-
return n1 < n2 ^ n1 < 0 != n2 < 0;
714+
return (n1 < n2) ^ ((n1 < 0) != (n2 < 0));
715715
}
716716

717717
/**
@@ -741,7 +741,7 @@ public static boolean isOdd(final long n) {
741741
* bit is at position zero.
742742
* @return a one if the bit at bitPos is a one, otherwise zero.
743743
*/
744-
public static final int bitAt(final long number, final int bitPos) {
744+
public static int bitAt(final long number, final int bitPos) {
745745
return (number & (1L << bitPos)) > 0 ? 1 : 0;
746746
}
747747

@@ -751,7 +751,7 @@ public static final int bitAt(final long number, final int bitPos) {
751751
* @return the number of decimal digits of the number n
752752
*/
753753
public static int numDigits(long n) {
754-
if (n % 10 == 0) { n++; }
754+
if ((n % 10) == 0) { n++; }
755755
return (int) ceil(log(n) / log(10));
756756
}
757757

@@ -898,39 +898,6 @@ public static void fill(final MemorySegment seg, final long offsetBytes, final l
898898
slice.fill(value);
899899
}
900900

901-
/**
902-
* Returns true if the two given MemorySegments refer to the same backing resource,
903-
* which is either an off-heap memory location and size, or the same on-heap array object.
904-
*
905-
* <p>If both segment are off-heap, they both must have the same starting address and the same size.</p>
906-
*
907-
* <p>For on-heap segments, both segments must be based on or derived from the same array object and neither segment
908-
* can be read-only.</p>
909-
*
910-
* <p>Returns false if either argument is null;</p>
911-
*
912-
* @param seg1 The first given MemorySegment
913-
* @param seg2 The second given MemorySegment
914-
* @return true if both MemorySegments are determined to be the same backing memory.
915-
*/
916-
public static boolean isSameResource(final MemorySegment seg1, final MemorySegment seg2) {
917-
if ((seg1 == null) || (seg2 == null)) { return false; }
918-
if (!seg1.scope().isAlive() || !seg2.scope().isAlive()) {
919-
throw new IllegalArgumentException("Both arguments must be alive.");
920-
}
921-
final boolean seg1Native = seg1.isNative();
922-
final boolean seg2Native = seg2.isNative();
923-
if (seg1Native ^ seg2Native) { return false; }
924-
if (seg1Native && seg2Native) { //both off heap
925-
return (seg1.address() == seg2.address()) && (seg1.byteSize() == seg2.byteSize());
926-
}
927-
//both on heap
928-
if (seg1.isReadOnly() || seg2.isReadOnly()) {
929-
throw new IllegalArgumentException("Cannot determine 'isSameBackingMemory(..)' on heap if either MemorySegment is Read-only.");
930-
}
931-
return (seg1.heapBase().orElse(null) == seg2.heapBase().orElse(null));
932-
}
933-
934901
/**
935902
* Request a new heap MemorySegment with the given capacityBytes and either 8-byte aligned or one byte aligned.
936903
*

src/main/java/org/apache/datasketches/hll/AbstractCoupons.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ abstract class AbstractCoupons extends HllSketchImpl {
9393

9494
@Override
9595
int getUpdatableSerializationBytes() {
96-
return getMemDataStart() + (4 << getLgCouponArrInts());
96+
return getSegDataStart() + (4 << getLgCouponArrInts());
9797
}
9898

9999
@Override

src/main/java/org/apache/datasketches/hll/AbstractHllArray.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ int getCompactSerializationBytes() {
145145
}
146146

147147
@Override
148-
int getMemDataStart() {
148+
int getSegDataStart() {
149149
return HLL_BYTE_ARR_START;
150150
}
151151

src/main/java/org/apache/datasketches/hll/AuxHashMap.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919

2020
package org.apache.datasketches.hll;
2121

22+
import java.lang.foreign.MemorySegment;
23+
2224
import org.apache.datasketches.common.SketchesStateException;
25+
import org.apache.datasketches.common.MemorySegmentStatus;
2326

2427
/**
2528
* @author Lee Rhodes
2629
*/
27-
interface AuxHashMap {
30+
interface AuxHashMap extends MemorySegmentStatus {
2831

2932
AuxHashMap copy();
3033

@@ -40,10 +43,15 @@ interface AuxHashMap {
4043

4144
int getUpdatableSizeBytes();
4245

43-
boolean isMemory();
46+
@Override
47+
boolean hasMemorySegment();
4448

49+
@Override
4550
boolean isOffHeap();
4651

52+
@Override
53+
boolean isSameResource(MemorySegment seg);
54+
4755
/**
4856
* Adds the slotNo and value to the aux array.
4957
* @param slotNo the index from the HLL array

0 commit comments

Comments
 (0)