Skip to content

Commit 23f7c29

Browse files
authored
Merge pull request #670 from apache/ffm_phase3
FFM phase3
2 parents 9c80116 + 2c35303 commit 23f7c29

37 files changed

Lines changed: 2801 additions & 965 deletions

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ under the License.
3333

3434
<groupId>org.apache.datasketches</groupId>
3535
<artifactId>datasketches-java</artifactId>
36-
<version>8.0.0-SNAPSHOT</version>
36+
<version>9.0.0-SNAPSHOT</version>
3737
<packaging>jar</packaging>
3838

3939
<name>${project.artifactId}</name>
@@ -190,7 +190,7 @@ under the License.
190190
<configuration>
191191
<rules>
192192
<requireJavaVersion>
193-
<version>[22,)</version> <!-- java.version -->
193+
<version>[24,)</version> <!-- java.version -->
194194
</requireJavaVersion>
195195
<requireMavenVersion>
196196
<version>[${maven.version},4.0.0)</version>

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ public interface MemorySegmentStatus {
4444
* Returns true if an internally referenced MemorySegment has the same backing resource as <i>that</i>,
4545
* or equivalently, if their two memory regions overlap. This applies to both on-heap and off-heap MemorySegments.
4646
*
47-
* <p>This returns false if either segment is <i>null</i> or not alive.</p>
48-
*
4947
* <p><b>Note:</b> If both segments are on-heap and not read-only, it can be determined if they were derived from
5048
* the same backing memory (array). However, this is not always possible off-heap. Because of this asymmetry, this definition
5149
* of "isSameResource" is confined to the existence of an overlap.</p>
@@ -59,8 +57,6 @@ public interface MemorySegmentStatus {
5957
* Returns true if the two given MemorySegments have to the same backing resource, or equivalently,
6058
* if the two memory regions overlap. This applies to both on-heap and off-heap MemorySegments.
6159
*
62-
* <p>This returns false if either segment is <i>null</i> or not alive.</p>
63-
*
6460
* <p><b>Note:</b> If both segments are on-heap and not read-only, it can be determined if they were derived from
6561
* the same backing memory (array). However, this is not always possible off-heap. Because of this asymmetry, this definition
6662
* of "isSameResource" is confined to the existence of an overlap.</p>
@@ -70,7 +66,6 @@ public interface MemorySegmentStatus {
7066
* @return true if the two given MemorySegments have to the same backing resource.
7167
*/
7268
static boolean isSameResource(final MemorySegment seg1, final MemorySegment seg2) {
73-
if ((seg1 == null) || (seg2 == null) || !seg1.scope().isAlive() || !seg2.scope().isAlive()) { return false; }
7469
final Optional<MemorySegment> opt = seg1.asOverlappingSlice(seg2);
7570
return opt.isPresent();
7671
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,19 @@ public static long floorPowerOf2(final long n) {
424424
return Long.highestOneBit(n);
425425
}
426426

427+
/**
428+
* This is a long integer equivalent to <i>Math.ceil(n / (double)(1 << k))</i>
429+
* where: <i>0 &lt; k &le; 6</i> and <i>n</i> is a non-negative long.
430+
* These limits are not checked for speed.
431+
* @param n the input dividend as a positive long greater than zero.
432+
* @param k the input divisor exponent of 2 as a positive integer where 0 &lt; k &le; 6.
433+
* @return the long integer equivalent to <i>Math.ceil(n / 2^k)</i>.
434+
*/
435+
public static long ceilingMultiple2expK(final long n, final int k) {
436+
final long mask = (1L << k) - 1L;
437+
return (n & mask) > 0 ? (n >>> k) + 1 : n >>> k;
438+
}
439+
427440
/**
428441
* Computes the inverse integer power of 2: 1/(2^e) = 2^(-e).
429442
* @param e a positive value between 0 and 1023 inclusive
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.datasketches.common.positional;
21+
22+
/**
23+
* Position operation violation.
24+
*/
25+
public class PositionInvariantsException extends RuntimeException {
26+
private static final long serialVersionUID = 1L;
27+
28+
/**
29+
* The associated position operation violated one of the positional invariants.
30+
*
31+
* <p>The invariants equation is {@code 0 <= start <= position <= end <= capacity}.</p>
32+
*
33+
* @param details of the violation.
34+
*/
35+
public PositionInvariantsException(final String details) {
36+
super(details);
37+
}
38+
}
39+
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.datasketches.common.positional;
21+
22+
/**
23+
* Defines the relative positional API.
24+
* This is different from and simpler than Java ByteBuffer positional API.
25+
* <ul><li>All based on longs instead of ints.</li>
26+
* <li>Eliminated "mark". Mark is rarely used and confusing with its silent side effects.</li>
27+
* <li>The invariants are {@code 0 <= start <= position <= end <= capacity}.</li>
28+
* <li>It always starts up as (0, 0, capacity, capacity).</li>
29+
* <li>You set (start, position, end) in one call with
30+
* {@link #setStartPositionEnd(long, long, long)}</li>
31+
* <li>Position can be set directly or indirectly when using the positional get/put methods.
32+
* <li>Added incrementPosition(long), which is much easier when you know the increment.</li>
33+
* <li>This approach eliminated a number of methods and checks, and has no unseen side effects,
34+
* e.g., mark being invalidated.</li>
35+
* <li>Clearer method naming (IMHO).</li>
36+
* </ul>
37+
*
38+
* @author Lee Rhodes
39+
*/
40+
public interface Positional {
41+
42+
/**
43+
* Gets an instance of this Positional.
44+
* @param capacity the upper limit of positional range.
45+
* @return an instance of Positional.
46+
*/
47+
static Positional getInstance(final long capacity) {
48+
return new PositionalImpl(capacity);
49+
}
50+
51+
/**
52+
* Increments the current position by the given increment.
53+
* @param increment the given increment
54+
* @return this Positional
55+
*/
56+
Positional incrementPosition(long increment);
57+
58+
/**
59+
* Gets the end position
60+
* @return the end position
61+
*/
62+
long getEnd();
63+
64+
/**
65+
* Gets the current position
66+
* @return the current position
67+
*/
68+
long getPosition();
69+
70+
/**
71+
* Gets start position
72+
* @return start position
73+
*/
74+
long getStart();
75+
76+
/**
77+
* The number of elements remaining between the current position and the end position
78+
* @return {@code (end - position)}
79+
*/
80+
long getRemaining();
81+
82+
/**
83+
* Returns true if there are elements remaining between the current position and the end position
84+
* @return {@code (end - position) > 0}
85+
*/
86+
boolean hasRemaining();
87+
88+
/**
89+
* Resets the current position to the start position,
90+
* This does not modify any data.
91+
* @return this Positional
92+
*/
93+
Positional resetPosition();
94+
95+
/**
96+
* Sets the current position.
97+
* Checks that the positional invariants are not violated.
98+
* @param position the given current position.
99+
* @return this Positional
100+
* @throws PositionInvariantsException if positional invariants have been violated.
101+
*/
102+
Positional setPosition(long position);
103+
104+
/**
105+
* Sets start position, current position, and end position.
106+
* Checks that the positional invariants are not violated.
107+
* @param start the start position in the buffer
108+
* @param position the current position between the start and end
109+
* @param end the end position in the buffer
110+
* @return this Positional
111+
* @throws PositionInvariantsException if positional invariants have been violated.
112+
*/
113+
Positional setStartPositionEnd(
114+
long start,
115+
long position,
116+
long end);
117+
118+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.datasketches.common.positional;
21+
22+
/**
23+
* This implements the positional API.
24+
* This is different from and simpler than Java BufferImpl positional approach.
25+
* <ul><li>All based on longs instead of ints.</li>
26+
* <li>Eliminated "mark". Rarely used and confusing with its silent side effects.</li>
27+
* <li>The invariants are {@code 0 <= start <= position <= end <= capacity}.</li>
28+
* <li>It always starts up as (0, 0, capacity, capacity).</li>
29+
* <li>You set (start, position, end) in one call with <i>setStartPositionEnd(long, long, long)</i></li>
30+
* <li>Position can be set directly or indirectly when using the positional get/put methods.
31+
* <li>Added incrementPosition(long), which is much easier when you know the increment.</li>
32+
* <li>This approach eliminated a number of methods and checks, and has no unseen side effects,
33+
* e.g., mark being invalidated.</li>
34+
* <li>Clearer method naming (IMHO).</li>
35+
* </ul>
36+
*
37+
* @author Lee Rhodes
38+
*/
39+
class PositionalImpl implements Positional {
40+
private final long capacity;
41+
private long start = 0;
42+
private long pos = 0;
43+
private long end;
44+
45+
/**
46+
* Construct with total capacity.
47+
* @param capacity the upper limit of positional range.
48+
*/
49+
PositionalImpl(
50+
final long capacity) {
51+
this.capacity = end = capacity;
52+
}
53+
54+
@Override
55+
public final PositionalImpl incrementPosition(final long increment) {
56+
pos += increment;
57+
return this;
58+
}
59+
60+
@Override
61+
public final long getEnd() {
62+
return end;
63+
}
64+
65+
@Override
66+
public final long getPosition() {
67+
return pos;
68+
}
69+
70+
@Override
71+
public final long getStart() {
72+
return start;
73+
}
74+
75+
@Override
76+
public final long getRemaining() {
77+
return end - pos;
78+
}
79+
80+
@Override
81+
public final boolean hasRemaining() {
82+
return (end - pos) > 0;
83+
}
84+
85+
@Override
86+
public final PositionalImpl resetPosition() {
87+
pos = start;
88+
return this;
89+
}
90+
91+
@Override
92+
public final PositionalImpl setPosition(final long position) {
93+
checkInvariants(start, position, end, capacity);
94+
pos = position;
95+
return this;
96+
}
97+
98+
@Override
99+
public final PositionalImpl setStartPositionEnd(final long start, final long position, final long end) {
100+
checkInvariants(start, position, end, capacity);
101+
this.start = start;
102+
this.end = end;
103+
pos = position;
104+
return this;
105+
}
106+
107+
//RESTRICTED
108+
109+
/**
110+
* The invariants equation is: {@code 0 <= start <= position <= end <= capacity}.
111+
* If this equation is violated an <i>PositionInvariantsException</i> will be thrown.
112+
* @param start the lowest start position
113+
* @param pos the current position
114+
* @param end the highest position
115+
* @param cap the capacity of the backing buffer.
116+
*/
117+
private static final void checkInvariants(final long start, final long pos, final long end,
118+
final long cap) {
119+
if ((start | pos | end | cap | (pos - start) | (end - pos) | (cap - end) ) < 0L) {
120+
throw new PositionInvariantsException(
121+
"Violation of Invariants: "
122+
+ "start: " + start
123+
+ " <= pos: " + pos
124+
+ " <= end: " + end
125+
+ " <= cap: " + cap
126+
+ "; (pos - start): " + (pos - start)
127+
+ ", (end - pos): " + (end - pos)
128+
+ ", (cap - end): " + (cap - end)
129+
);
130+
}
131+
}
132+
133+
}

0 commit comments

Comments
 (0)