forked from wildfly/wildfly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request wildfly#17096 from pferraro/WFLY-18315
WFLY-18315 Optimize payload of distributed session metadata
- Loading branch information
Showing
211 changed files
with
3,982 additions
and
1,478 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
clustering/ee/cache/src/main/java/org/wildfly/clustering/ee/cache/function/Remappable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright The WildFly Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.wildfly.clustering.ee.cache.function; | ||
|
||
/** | ||
* Implemented by cache value types that support copy-on-write operations. | ||
* @author Paul Ferraro | ||
* @param <V> the cache value type | ||
* @param <O> the operand type | ||
*/ | ||
public interface Remappable<V extends Remappable<V, O>, O> { | ||
|
||
/** | ||
* Returns a new instance of this object with the specified operand applied. | ||
* @param operand a value applied to the replacement value | ||
* @return a replacement value | ||
*/ | ||
V remap(O operand); | ||
} |
32 changes: 32 additions & 0 deletions
32
...ng/ee/cache/src/main/java/org/wildfly/clustering/ee/cache/function/RemappingFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/* | ||
* Copyright The WildFly Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.wildfly.clustering.ee.cache.function; | ||
|
||
import java.util.function.BiFunction; | ||
|
||
/** | ||
* Generic function for use with {@link java.util.Map#compute(Object, BiFunction)} operations using {@link Remappable} values. | ||
* @author Paul Ferraro | ||
* @param <V> the cache value type | ||
* @param <O> the operand type | ||
*/ | ||
public class RemappingFunction<V extends Remappable<V, O>, O> implements BiFunction<Object, V, V> { | ||
|
||
private final O operand; | ||
|
||
public RemappingFunction(O operand) { | ||
this.operand = operand; | ||
} | ||
|
||
public O getOperand() { | ||
return this.operand; | ||
} | ||
|
||
@Override | ||
public V apply(Object key, V value) { | ||
return (value != null) ? value.remap(this.operand) : null; | ||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
clustering/ee/cache/src/main/java/org/wildfly/clustering/ee/cache/offset/Offset.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* Copyright The WildFly Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.wildfly.clustering.ee.cache.offset; | ||
|
||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.util.function.BiFunction; | ||
import java.util.function.Predicate; | ||
import java.util.function.Supplier; | ||
import java.util.function.UnaryOperator; | ||
|
||
/** | ||
* Encapsulates an offset that can be applied to a value. | ||
* @author Paul Ferraro | ||
* @param <V> the value to which the offset can be applied | ||
*/ | ||
public interface Offset<V> extends UnaryOperator<V> { | ||
/** | ||
* Returns true if this offset is zero, false otherwise. | ||
* @return true if this offset is zero, false otherwise. | ||
*/ | ||
boolean isZero(); | ||
|
||
static Offset<Duration> forDuration(Duration offset) { | ||
return offset.isZero() ? DurationOffset.ZERO : new DurationOffset(offset); | ||
} | ||
|
||
static Offset<Instant> forInstant(Duration offset) { | ||
return offset.isZero() ? InstantOffset.ZERO : new InstantOffset(offset); | ||
} | ||
|
||
class DefaultOffset<O, V> implements Offset<V>, Supplier<O> { | ||
|
||
private final O value; | ||
private final Predicate<O> isZero; | ||
private final BiFunction<V, O, V> applicator; | ||
|
||
DefaultOffset(O value, Predicate<O> isZero, BiFunction<V, O, V> applicator) { | ||
this.value = value; | ||
this.isZero = isZero; | ||
this.applicator = applicator; | ||
} | ||
|
||
@Override | ||
public V apply(V value) { | ||
return this.isZero() ? value : this.applicator.apply(value, this.value); | ||
} | ||
|
||
@Override | ||
public boolean isZero() { | ||
return this.isZero.test(this.value); | ||
} | ||
|
||
@Override | ||
public O get() { | ||
return this.value; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return this.value.hashCode(); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object object) { | ||
if (!(object instanceof Offset)) return false; | ||
@SuppressWarnings("unchecked") | ||
DefaultOffset<O, V> offset = (DefaultOffset<O, V>) object; | ||
return this.value.equals(offset.value); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return this.value.toString(); | ||
} | ||
} | ||
|
||
class TemporalOffset<V> extends DefaultOffset<Duration, V> { | ||
private static final Predicate<Duration> IS_ZERO = Duration::isZero; | ||
|
||
TemporalOffset(Duration offset, BiFunction<V, Duration, V> applicator) { | ||
super(offset, IS_ZERO, applicator); | ||
} | ||
} | ||
|
||
class DurationOffset extends TemporalOffset<Duration> { | ||
static final Offset<Duration> ZERO = new DurationOffset(Duration.ZERO); | ||
private static final BiFunction<Duration, Duration, Duration> DURATION_APPLICATOR = Duration::plus; | ||
|
||
DurationOffset(Duration value) { | ||
super(value, DURATION_APPLICATOR); | ||
} | ||
} | ||
|
||
class InstantOffset extends TemporalOffset<Instant> { | ||
static final Offset<Instant> ZERO = new InstantOffset(Duration.ZERO); | ||
private static final BiFunction<Instant, Duration, Instant> INSTANT_APPLICATOR = Instant::plus; | ||
|
||
InstantOffset(Duration value) { | ||
super(value, INSTANT_APPLICATOR); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...in/java/org/wildfly/clustering/ee/cache/offset/OffsetSerializationContextInitializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright The WildFly Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.wildfly.clustering.ee.cache.offset; | ||
|
||
import java.time.Duration; | ||
|
||
import org.infinispan.protostream.SerializationContext; | ||
import org.infinispan.protostream.SerializationContextInitializer; | ||
import org.kohsuke.MetaInfServices; | ||
import org.wildfly.clustering.marshalling.protostream.AbstractSerializationContextInitializer; | ||
import org.wildfly.clustering.marshalling.protostream.FunctionalMarshaller; | ||
|
||
/** | ||
* @author Paul Ferraro | ||
*/ | ||
@MetaInfServices(SerializationContextInitializer.class) | ||
public class OffsetSerializationContextInitializer extends AbstractSerializationContextInitializer { | ||
|
||
@Override | ||
public void registerMarshallers(SerializationContext context) { | ||
context.registerMarshaller(new FunctionalMarshaller<>(Offset.DurationOffset.class, Duration.class, Offset.DurationOffset::get, Offset.DurationOffset::new)); | ||
context.registerMarshaller(new FunctionalMarshaller<>(Offset.InstantOffset.class, Duration.class, Offset.InstantOffset::get, Offset.InstantOffset::new)); | ||
} | ||
} |
135 changes: 135 additions & 0 deletions
135
clustering/ee/cache/src/main/java/org/wildfly/clustering/ee/cache/offset/OffsetValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright The WildFly Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package org.wildfly.clustering.ee.cache.offset; | ||
|
||
import java.time.Duration; | ||
import java.time.Instant; | ||
import java.util.Objects; | ||
import java.util.function.BiFunction; | ||
import java.util.function.Function; | ||
import java.util.function.Supplier; | ||
|
||
import org.wildfly.common.function.Functions; | ||
|
||
/** | ||
* Encapsulates a value that is offset from some basis, and updated via {@link OffsetValue#set(Object)}. | ||
* @author Paul Ferraro | ||
* @param <V> the value type | ||
*/ | ||
public interface OffsetValue<V> extends Value<V> { | ||
|
||
/** | ||
* Returns the basis from which the associated offset will be applied. | ||
* @return the basis from which the associated offset will be applied. | ||
*/ | ||
V getBasis(); | ||
|
||
/** | ||
* Returns the current value, computed by applying the current offset to the basis. | ||
* @return the computed value | ||
*/ | ||
@Override | ||
default V get() { | ||
return this.getOffset().apply(this.getBasis()); | ||
} | ||
|
||
/** | ||
* The current offset. | ||
* @return an offset | ||
*/ | ||
Offset<V> getOffset(); | ||
|
||
/** | ||
* Sets the current offset. | ||
* @param offset an offset | ||
*/ | ||
default void setOffset(Offset<V> offset) { | ||
this.set(offset.apply(this.getBasis())); | ||
} | ||
|
||
/** | ||
* Returns a new offset value based on the current value. | ||
* @return a new offset value | ||
*/ | ||
OffsetValue<V> rebase(); | ||
|
||
static OffsetValue<Duration> from(Duration duration) { | ||
return new DurationOffsetValue(Functions.constantSupplier(duration)); | ||
} | ||
|
||
static OffsetValue<Instant> from(Instant instant) { | ||
return new InstantOffsetValue(Functions.constantSupplier(instant)); | ||
} | ||
|
||
class DefaultOffsetValue<O, V> extends AbstractValue<V> implements OffsetValue<V> { | ||
private final BiFunction<V, V, O> factory; | ||
private final Function<O, Offset<V>> offsetFactory; | ||
private final Function<Supplier<V>, OffsetValue<V>> offsetValueFactory; | ||
private final Supplier<V> basis; | ||
private final O zero; | ||
|
||
private volatile Offset<V> offset; | ||
|
||
DefaultOffsetValue(Supplier<V> basis, O zero, BiFunction<V, V, O> factory, Function<O, Offset<V>> offsetFactory, Function<Supplier<V>, OffsetValue<V>> offsetValueFactory) { | ||
this.factory = factory; | ||
this.offsetFactory = offsetFactory; | ||
this.offsetValueFactory = offsetValueFactory; | ||
this.zero = zero; | ||
this.basis = basis; | ||
this.offset = this.offsetFactory.apply(zero); | ||
} | ||
|
||
@Override | ||
public V getBasis() { | ||
return this.basis.get(); | ||
} | ||
|
||
@Override | ||
public void set(V value) { | ||
V basis = this.getBasis(); | ||
this.offset = this.offsetFactory.apply(Objects.equals(basis, value) ? this.zero : this.factory.apply(basis, value)); | ||
} | ||
|
||
@Override | ||
public void setOffset(Offset<V> offset) { | ||
this.offset = offset; | ||
} | ||
|
||
@Override | ||
public Offset<V> getOffset() { | ||
return this.offset; | ||
} | ||
|
||
@Override | ||
public OffsetValue<V> rebase() { | ||
return this.offsetValueFactory.apply(this); | ||
} | ||
} | ||
|
||
static class TemporalOffsetValue<V> extends DefaultOffsetValue<Duration, V> { | ||
|
||
TemporalOffsetValue(Supplier<V> basis, BiFunction<V, V, Duration> factory, Function<Duration, Offset<V>> offsetFactory, Function<Supplier<V>, OffsetValue<V>> offsetValueFactory) { | ||
super(basis, Duration.ZERO, factory, offsetFactory, offsetValueFactory); | ||
} | ||
} | ||
|
||
static class DurationOffsetValue extends TemporalOffsetValue<Duration> { | ||
private static final BiFunction<Duration, Duration, Duration> MINUS = Duration::minus; | ||
private static final BiFunction<Duration, Duration, Duration> FACTORY = MINUS.andThen(Duration::negated); | ||
|
||
DurationOffsetValue(Supplier<Duration> basis) { | ||
super(basis, FACTORY, Offset::forDuration, DurationOffsetValue::new); | ||
} | ||
} | ||
|
||
static class InstantOffsetValue extends TemporalOffsetValue<Instant> { | ||
private static final BiFunction<Instant, Instant, Duration> FACTORY = Duration::between; | ||
|
||
InstantOffsetValue(Supplier<Instant> basis) { | ||
super(basis, FACTORY, Offset::forInstant, InstantOffsetValue::new); | ||
} | ||
} | ||
} |
Oops, something went wrong.