Run via IDE with {@link #main} or as an uber-jar: + *
+ * java -jar target/benchmarks.jar JmhCacheMetricsSerializationBenchmark + *+ */ +@State(Scope.Thread) +@OutputTimeUnit(NANOSECONDS) +@BenchmarkMode(AverageTime) +@Warmup(iterations = 3, time = 10, timeUnit = SECONDS) +@Measurement(iterations = 5, time = 10, timeUnit = SECONDS) +public class JmhCacheMetricsSerializationBenchmark { + /** Buffer capacity — large enough for a fully serialized CacheMetricsMessage. */ + private static final int BUF_CAPACITY = 8 * 1024; + + // ----- New approach (MessageSerializer) ----- + + /** New-style message. */ + private CacheMetricsMessage newMsg; + + /** New-style serializer. */ + private CacheMetricsMessageSerializer newSerializer; + + /** Writer for new-style benchmarks. */ + private DirectMessageWriter newWriter; + + /** Reader for new-style benchmarks. */ + private DirectMessageReader newReader; + + /** Write buffer for new-style benchmarks. */ + private ByteBuffer newWriteBuf; + + /** Pre-filled read buffer for new-style benchmarks. */ + private ByteBuffer newReadBuf; + + /** Reusable deserialization target for new-style benchmarks. */ + private CacheMetricsMessage newReadTarget; + + // ----- Legacy approach (inline writeTo/readFrom) ----- + + /** Legacy message. */ + private LegacyCacheMetricsMessage legacyMsg; + + /** Writer for legacy benchmarks. */ + private DirectMessageWriter legacyWriter; + + /** Reader for legacy benchmarks. */ + private DirectMessageReader legacyReader; + + /** Write buffer for legacy benchmarks. */ + private ByteBuffer legacyWriteBuf; + + /** Pre-filled read buffer for legacy benchmarks. */ + private ByteBuffer legacyReadBuf; + + /** Reusable deserialization target for legacy benchmarks. */ + private LegacyCacheMetricsMessage legacyReadTarget; + + /** */ + @Setup + public void setup() throws Exception { + MessageFactory factory = new IgniteMessageFactoryImpl( + new MessageFactoryProvider[]{new GridIoMessageFactory(jdk(), U.gridClassLoader())} + ); + + // --- New approach setup --- + newMsg = buildNewMessage(); + newSerializer = new CacheMetricsMessageSerializer(); + newWriteBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + newReadBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + newWriter = new DirectMessageWriter(factory); + newReader = new DirectMessageReader(factory, null); + + newWriter.setBuffer(newWriteBuf); + + if (!newSerializer.writeTo(newMsg, newWriter)) + throw new IllegalStateException("Write buffer is too small for new message"); + + newWriteBuf.flip(); + newWriteBuf.position(Short.BYTES); // skip directType header + newReadBuf.put(newWriteBuf); + newReadBuf.flip(); + + newWriteBuf.clear(); + newWriter.reset(); + + newReadTarget = new CacheMetricsMessage(); + + // --- Legacy approach setup --- + legacyMsg = buildLegacyMessage(); + legacyWriteBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + legacyReadBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + legacyWriter = new DirectMessageWriter(factory); + legacyReader = new DirectMessageReader(factory, null); + + legacyWriter.setBuffer(legacyWriteBuf); + + if (!legacyMsg.writeTo(legacyWriteBuf, legacyWriter)) + throw new IllegalStateException("Write buffer is too small for legacy message"); + + legacyWriteBuf.flip(); + legacyWriteBuf.position(Short.BYTES); // skip directType header + legacyReadBuf.put(legacyWriteBuf); + legacyReadBuf.flip(); + + legacyWriteBuf.clear(); + legacyWriter.reset(); + + legacyReadTarget = new LegacyCacheMetricsMessage(); + } + + // ----- New approach benchmarks ----- + + /** Measures serialization cost using the new {@code MessageSerializer} approach. */ + @Benchmark + public boolean newWriteTo() { + newWriteBuf.clear(); + newWriter.reset(); + newWriter.setBuffer(newWriteBuf); + + return newSerializer.writeTo(newMsg, newWriter); + } + + /** Measures deserialization cost using the new {@code MessageSerializer} approach. */ + @Benchmark + public boolean newReadFrom() { + newReadBuf.rewind(); + newReader.reset(); + newReader.setBuffer(newReadBuf); + + return newSerializer.readFrom(newReadTarget, newReader); + } + + // ----- Legacy approach benchmarks ----- + + /** Measures serialization cost using the legacy inline {@code writeTo} approach. */ + @Benchmark + public boolean legacyWriteTo() { + legacyWriteBuf.clear(); + legacyWriter.reset(); + + return legacyMsg.writeTo(legacyWriteBuf, legacyWriter); + } + + /** Measures deserialization cost using the legacy inline {@code readFrom} approach. */ + @Benchmark + public boolean legacyReadFrom() { + legacyReadBuf.rewind(); + legacyReader.reset(); + + return legacyReadTarget.readFrom(legacyReadBuf, legacyReader); + } + + /** */ + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(new String[]{JmhCacheMetricsSerializationBenchmark.class.getSimpleName()}); + } + + // ----- helpers ----- + + /** Builds a fully populated {@link CacheMetricsMessage}. */ + private static CacheMetricsMessage buildNewMessage() { + var msg = new CacheMetricsMessage(); + + populateFields(msg); + + return msg; + } + + /** Builds a fully populated {@link LegacyCacheMetricsMessage}. */ + private static LegacyCacheMetricsMessage buildLegacyMessage() { + var msg = new LegacyCacheMetricsMessage(); + + populateFields(msg); + + return msg; + } + + /** + * Populates all 87 fields with realistic non-zero values. + * Works for both new and legacy messages via direct field assignment + * (both classes have the same public fields). + */ + private static void populateFields(CacheMetricsMessage msg) { + msg.cacheGets = 100_000L; + msg.cachePuts = 50_000L; + msg.entryProcessorPuts = 1_000L; + msg.entryProcessorReadOnlyInvocations = 2_000L; + msg.entryProcessorAverageInvocationTime = 0.5f; + msg.entryProcessorInvocations = 3_000L; + msg.entryProcessorRemovals = 500L; + msg.entryProcessorMisses = 200L; + msg.entryProcessorHits = 2_800L; + msg.entryProcessorMissPercentage = 6.67f; + msg.entryProcessorHitPercentage = 93.33f; + msg.entryProcessorMaxInvocationTime = 10.0f; + msg.entryProcessorMinInvocationTime = 0.01f; + msg.cacheHits = 95_000L; + msg.cacheMisses = 5_000L; + msg.cacheTxCommits = 10_000L; + msg.cacheTxRollbacks = 100L; + msg.cacheEvictions = 1_000L; + msg.cacheRemovals = 2_000L; + msg.averagePutTime = 0.3f; + msg.averageGetTime = 0.1f; + msg.averageRemoveTime = 0.2f; + msg.averageTxCommitTime = 1.5f; + msg.averageTxRollbackTime = 0.8f; + msg.cacheName = "test-cache"; + msg.offHeapGets = 80_000L; + msg.offHeapPuts = 40_000L; + msg.offHeapRemoves = 1_500L; + msg.offHeapEvicts = 500L; + msg.offHeapHits = 75_000L; + msg.offHeapMisses = 5_000L; + msg.offHeapEntriesCnt = 100_000L; + msg.heapEntriesCnt = 10_000L; + msg.offHeapPrimaryEntriesCnt = 70_000L; + msg.offHeapBackupEntriesCnt = 30_000L; + msg.offHeapAllocatedSize = 1_073_741_824L; + msg.size = 100_000; + msg.cacheSize = 100_000L; + msg.keySize = 100_000; + msg.empty = false; + msg.dhtEvictQueueCurrSize = 0; + msg.txThreadMapSize = 8; + msg.txXidMapSize = 16; + msg.txCommitQueueSize = 4; + msg.txPrepareQueueSize = 2; + msg.txStartVerCountsSize = 32; + msg.txCommittedVersionsSize = 64; + msg.txRolledbackVersionsSize = 8; + msg.txDhtThreadMapSize = 8; + msg.txDhtXidMapSize = 16; + msg.txDhtCommitQueueSize = 4; + msg.txDhtPrepareQueueSize = 2; + msg.txDhtStartVerCountsSize = 32; + msg.txDhtCommittedVersionsSize = 64; + msg.txDhtRolledbackVersionsSize = 8; + msg.writeBehindEnabled = true; + msg.writeBehindFlushSize = 10_240; + msg.writeBehindFlushThreadCnt = 4; + msg.writeBehindFlushFreq = 5_000L; + msg.writeBehindStoreBatchSize = 512; + msg.writeBehindTotalCriticalOverflowCnt = 0; + msg.writeBehindCriticalOverflowCnt = 0; + msg.writeBehindErrorRetryCnt = 0; + msg.writeBehindBufSize = 1_024; + msg.totalPartitionsCnt = 1_024; + msg.rebalancingPartitionsCnt = 0; + msg.rebalancedKeys = 500_000L; + msg.estimatedRebalancingKeys = 500_000L; + msg.keysToRebalanceLeft = 0L; + msg.rebalancingKeysRate = 10_000L; + msg.rebalancingBytesRate = 1_048_576L; + msg.rebalanceStartTime = System.currentTimeMillis() - 60_000L; + msg.rebalanceFinishTime = System.currentTimeMillis(); + msg.rebalanceClearingPartitionsLeft = 0L; + msg.keyType = "java.lang.Integer"; + msg.valType = "java.lang.String"; + msg.storeByVal = true; + msg.statisticsEnabled = true; + msg.managementEnabled = false; + msg.readThrough = true; + msg.writeThrough = true; + msg.validForReading = true; + msg.validForWriting = true; + msg.txKeyCollisions = ""; + msg.idxRebuildInProgress = false; + msg.idxRebuildKeyProcessed = 0L; + msg.idxBuildPartitionsLeftCount = 0; + } + + /** Populates all fields for the legacy message (identical values). */ + private static void populateFields(LegacyCacheMetricsMessage msg) { + msg.cacheGets = 100_000L; + msg.cachePuts = 50_000L; + msg.entryProcessorPuts = 1_000L; + msg.entryProcessorReadOnlyInvocations = 2_000L; + msg.entryProcessorAverageInvocationTime = 0.5f; + msg.entryProcessorInvocations = 3_000L; + msg.entryProcessorRemovals = 500L; + msg.entryProcessorMisses = 200L; + msg.entryProcessorHits = 2_800L; + msg.entryProcessorMissPercentage = 6.67f; + msg.entryProcessorHitPercentage = 93.33f; + msg.entryProcessorMaxInvocationTime = 10.0f; + msg.entryProcessorMinInvocationTime = 0.01f; + msg.cacheHits = 95_000L; + msg.cacheMisses = 5_000L; + msg.cacheTxCommits = 10_000L; + msg.cacheTxRollbacks = 100L; + msg.cacheEvictions = 1_000L; + msg.cacheRemovals = 2_000L; + msg.averagePutTime = 0.3f; + msg.averageGetTime = 0.1f; + msg.averageRemoveTime = 0.2f; + msg.averageTxCommitTime = 1.5f; + msg.averageTxRollbackTime = 0.8f; + msg.cacheName = "test-cache"; + msg.offHeapGets = 80_000L; + msg.offHeapPuts = 40_000L; + msg.offHeapRemoves = 1_500L; + msg.offHeapEvicts = 500L; + msg.offHeapHits = 75_000L; + msg.offHeapMisses = 5_000L; + msg.offHeapEntriesCnt = 100_000L; + msg.heapEntriesCnt = 10_000L; + msg.offHeapPrimaryEntriesCnt = 70_000L; + msg.offHeapBackupEntriesCnt = 30_000L; + msg.offHeapAllocatedSize = 1_073_741_824L; + msg.size = 100_000; + msg.cacheSize = 100_000L; + msg.keySize = 100_000; + msg.empty = false; + msg.dhtEvictQueueCurrSize = 0; + msg.txThreadMapSize = 8; + msg.txXidMapSize = 16; + msg.txCommitQueueSize = 4; + msg.txPrepareQueueSize = 2; + msg.txStartVerCountsSize = 32; + msg.txCommittedVersionsSize = 64; + msg.txRolledbackVersionsSize = 8; + msg.txDhtThreadMapSize = 8; + msg.txDhtXidMapSize = 16; + msg.txDhtCommitQueueSize = 4; + msg.txDhtPrepareQueueSize = 2; + msg.txDhtStartVerCountsSize = 32; + msg.txDhtCommittedVersionsSize = 64; + msg.txDhtRolledbackVersionsSize = 8; + msg.writeBehindEnabled = true; + msg.writeBehindFlushSize = 10_240; + msg.writeBehindFlushThreadCnt = 4; + msg.writeBehindFlushFreq = 5_000L; + msg.writeBehindStoreBatchSize = 512; + msg.writeBehindTotalCriticalOverflowCnt = 0; + msg.writeBehindCriticalOverflowCnt = 0; + msg.writeBehindErrorRetryCnt = 0; + msg.writeBehindBufSize = 1_024; + msg.totalPartitionsCnt = 1_024; + msg.rebalancingPartitionsCnt = 0; + msg.rebalancedKeys = 500_000L; + msg.estimatedRebalancingKeys = 500_000L; + msg.keysToRebalanceLeft = 0L; + msg.rebalancingKeysRate = 10_000L; + msg.rebalancingBytesRate = 1_048_576L; + msg.rebalanceStartTime = System.currentTimeMillis() - 60_000L; + msg.rebalanceFinishTime = System.currentTimeMillis(); + msg.rebalanceClearingPartitionsLeft = 0L; + msg.keyType = "java.lang.Integer"; + msg.valType = "java.lang.String"; + msg.storeByVal = true; + msg.statisticsEnabled = true; + msg.managementEnabled = false; + msg.readThrough = true; + msg.writeThrough = true; + msg.validForReading = true; + msg.validForWriting = true; + msg.txKeyCollisions = ""; + msg.idxRebuildInProgress = false; + msg.idxRebuildKeyProcessed = 0L; + msg.idxBuildPartitionsLeftCount = 0; + } +} diff --git a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhNodeIdSerializationBenchmark.java b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhNodeIdSerializationBenchmark.java new file mode 100644 index 0000000000000..94df38b1a5781 --- /dev/null +++ b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhNodeIdSerializationBenchmark.java @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.benchmarks.jmh.communication; + +import java.nio.ByteBuffer; +import java.util.UUID; +import org.apache.ignite.internal.direct.DirectMessageReader; +import org.apache.ignite.internal.direct.DirectMessageWriter; +import org.apache.ignite.internal.managers.communication.GridIoMessageFactory; +import org.apache.ignite.internal.managers.communication.IgniteMessageFactoryImpl; +import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.plugin.extensions.communication.MessageFactory; +import org.apache.ignite.plugin.extensions.communication.MessageFactoryProvider; +import org.apache.ignite.spi.communication.tcp.messages.NodeIdMessage; +import org.apache.ignite.spi.communication.tcp.messages.NodeIdMessageSerializer; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; +import static org.apache.ignite.marshaller.Marshallers.jdk; +import static org.openjdk.jmh.annotations.Mode.AverageTime; + +/** + * Benchmark comparing legacy (inline {@code writeTo}/{@code readFrom}) vs new ({@code MessageSerializer}) + * serialization approaches for {@code NodeIdMessage} — the minimal possible message with a single UUID field. + * + *
This benchmark isolates the per-message overhead of both approaches by using the smallest + * possible message, complementing the {@link JmhCacheMetricsSerializationBenchmark} which measures + * throughput on a large (87-field) message. + * + *
Run via IDE with {@link #main} or as an uber-jar: + *
+ * java -jar target/benchmarks.jar JmhNodeIdSerializationBenchmark + *+ */ +@State(Scope.Thread) +@OutputTimeUnit(NANOSECONDS) +@BenchmarkMode(AverageTime) +@Warmup(iterations = 3, time = 10, timeUnit = SECONDS) +@Measurement(iterations = 5, time = 10, timeUnit = SECONDS) +public class JmhNodeIdSerializationBenchmark { + /** Buffer capacity — generous for a tiny message. */ + private static final int BUF_CAPACITY = 1024; + + // ----- New approach (MessageSerializer) ----- + + /** New-style message. */ + private NodeIdMessage newMsg; + + /** New-style serializer. */ + private NodeIdMessageSerializer newSerializer; + + /** Writer for new-style benchmarks. */ + private DirectMessageWriter newWriter; + + /** Reader for new-style benchmarks. */ + private DirectMessageReader newReader; + + /** Write buffer for new-style benchmarks. */ + private ByteBuffer newWriteBuf; + + /** Pre-filled read buffer for new-style benchmarks. */ + private ByteBuffer newReadBuf; + + /** Reusable deserialization target for new-style benchmarks. */ + private NodeIdMessage newReadTarget; + + // ----- Legacy approach (inline writeTo/readFrom) ----- + + /** Legacy message. */ + private LegacyNodeIdMessage legacyMsg; + + /** Writer for legacy benchmarks. */ + private DirectMessageWriter legacyWriter; + + /** Reader for legacy benchmarks. */ + private DirectMessageReader legacyReader; + + /** Write buffer for legacy benchmarks. */ + private ByteBuffer legacyWriteBuf; + + /** Pre-filled read buffer for legacy benchmarks. */ + private ByteBuffer legacyReadBuf; + + /** Reusable deserialization target for legacy benchmarks. */ + private LegacyNodeIdMessage legacyReadTarget; + + /** */ + @Setup + public void setup() throws Exception { + MessageFactory factory = new IgniteMessageFactoryImpl( + new MessageFactoryProvider[]{new GridIoMessageFactory(jdk(), U.gridClassLoader())} + ); + + var uuid = UUID.randomUUID(); + + // --- New approach setup --- + newMsg = new NodeIdMessage(uuid); + newSerializer = new NodeIdMessageSerializer(); + newWriteBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + newReadBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + newWriter = new DirectMessageWriter(factory); + newReader = new DirectMessageReader(factory, null); + + newWriter.setBuffer(newWriteBuf); + + if (!newSerializer.writeTo(newMsg, newWriter)) + throw new IllegalStateException("Write buffer is too small for new message"); + + newWriteBuf.flip(); + newWriteBuf.position(Short.BYTES); // skip directType header + newReadBuf.put(newWriteBuf); + newReadBuf.flip(); + + newWriteBuf.clear(); + newWriter.reset(); + + newReadTarget = new NodeIdMessage(); + + // --- Legacy approach setup --- + legacyMsg = new LegacyNodeIdMessage(uuid); + legacyWriteBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + legacyReadBuf = ByteBuffer.allocateDirect(BUF_CAPACITY); + legacyWriter = new DirectMessageWriter(factory); + legacyReader = new DirectMessageReader(factory, null); + + legacyWriter.setBuffer(legacyWriteBuf); + + if (!legacyMsg.writeTo(legacyWriteBuf, legacyWriter)) + throw new IllegalStateException("Write buffer is too small for legacy message"); + + legacyWriteBuf.flip(); + legacyWriteBuf.position(Short.BYTES); // skip directType header + legacyReadBuf.put(legacyWriteBuf); + legacyReadBuf.flip(); + + legacyWriteBuf.clear(); + legacyWriter.reset(); + + legacyReadTarget = new LegacyNodeIdMessage(); + } + + // ----- New approach benchmarks ----- + + /** Measures serialization cost using the new {@code MessageSerializer} approach. */ + @Benchmark + public boolean newWriteTo() { + newWriteBuf.clear(); + newWriter.reset(); + newWriter.setBuffer(newWriteBuf); + + return newSerializer.writeTo(newMsg, newWriter); + } + + /** Measures deserialization cost using the new {@code MessageSerializer} approach. */ + @Benchmark + public boolean newReadFrom() { + newReadBuf.rewind(); + newReader.reset(); + newReader.setBuffer(newReadBuf); + + return newSerializer.readFrom(newReadTarget, newReader); + } + + // ----- Legacy approach benchmarks ----- + + /** Measures serialization cost using the legacy inline {@code writeTo} approach. */ + @Benchmark + public boolean legacyWriteTo() { + legacyWriteBuf.clear(); + legacyWriter.reset(); + + return legacyMsg.writeTo(legacyWriteBuf, legacyWriter); + } + + /** Measures deserialization cost using the legacy inline {@code readFrom} approach. */ + @Benchmark + public boolean legacyReadFrom() { + legacyReadBuf.rewind(); + legacyReader.reset(); + + return legacyReadTarget.readFrom(legacyReadBuf, legacyReader); + } + + /** */ + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(new String[]{JmhNodeIdSerializationBenchmark.class.getSimpleName()}); + } +} diff --git a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/LegacyCacheMetricsMessage.java b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/LegacyCacheMetricsMessage.java new file mode 100644 index 0000000000000..9175f958a08b9 --- /dev/null +++ b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/LegacyCacheMetricsMessage.java @@ -0,0 +1,1541 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.benchmarks.jmh.communication; + +import java.nio.ByteBuffer; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * Legacy version of {@code CacheMetricsMessage} with inline {@code writeTo}/{@code readFrom} + * methods (the old code-generated approach). Used for benchmarking against the new + * {@code MessageSerializer}-based approach. + * + *
Contains the same 87 simple fields as the real {@code CacheMetricsMessage}. + */ +public class LegacyCacheMetricsMessage implements Message { + /** */ + public long cacheGets; + + /** */ + public long cachePuts; + + /** */ + public long entryProcessorPuts; + + /** */ + public long entryProcessorReadOnlyInvocations; + + /** */ + public float entryProcessorAverageInvocationTime; + + /** */ + public long entryProcessorInvocations; + + /** */ + public long entryProcessorRemovals; + + /** */ + public long entryProcessorMisses; + + /** */ + public long entryProcessorHits; + + /** */ + public float entryProcessorMissPercentage; + + /** */ + public float entryProcessorHitPercentage; + + /** */ + public float entryProcessorMaxInvocationTime; + + /** */ + public float entryProcessorMinInvocationTime; + + /** */ + public long cacheHits; + + /** */ + public long cacheMisses; + + /** */ + public long cacheTxCommits; + + /** */ + public long cacheTxRollbacks; + + /** */ + public long cacheEvictions; + + /** */ + public long cacheRemovals; + + /** */ + public float averagePutTime; + + /** */ + public float averageGetTime; + + /** */ + public float averageRemoveTime; + + /** */ + public float averageTxCommitTime; + + /** */ + public float averageTxRollbackTime; + + /** */ + public String cacheName; + + /** */ + public long offHeapGets; + + /** */ + public long offHeapPuts; + + /** */ + public long offHeapRemoves; + + /** */ + public long offHeapEvicts; + + /** */ + public long offHeapHits; + + /** */ + public long offHeapMisses; + + /** */ + public long offHeapEntriesCnt; + + /** */ + public long heapEntriesCnt; + + /** */ + public long offHeapPrimaryEntriesCnt; + + /** */ + public long offHeapBackupEntriesCnt; + + /** */ + public long offHeapAllocatedSize; + + /** */ + public int size; + + /** */ + public long cacheSize; + + /** */ + public int keySize; + + /** */ + public boolean empty; + + /** */ + public int dhtEvictQueueCurrSize; + + /** */ + public int txThreadMapSize; + + /** */ + public int txXidMapSize; + + /** */ + public int txCommitQueueSize; + + /** */ + public int txPrepareQueueSize; + + /** */ + public int txStartVerCountsSize; + + /** */ + public int txCommittedVersionsSize; + + /** */ + public int txRolledbackVersionsSize; + + /** */ + public int txDhtThreadMapSize; + + /** */ + public int txDhtXidMapSize; + + /** */ + public int txDhtCommitQueueSize; + + /** */ + public int txDhtPrepareQueueSize; + + /** */ + public int txDhtStartVerCountsSize; + + /** */ + public int txDhtCommittedVersionsSize; + + /** */ + public int txDhtRolledbackVersionsSize; + + /** */ + public boolean writeBehindEnabled; + + /** */ + public int writeBehindFlushSize; + + /** */ + public int writeBehindFlushThreadCnt; + + /** */ + public long writeBehindFlushFreq; + + /** */ + public int writeBehindStoreBatchSize; + + /** */ + public int writeBehindTotalCriticalOverflowCnt; + + /** */ + public int writeBehindCriticalOverflowCnt; + + /** */ + public int writeBehindErrorRetryCnt; + + /** */ + public int writeBehindBufSize; + + /** */ + public int totalPartitionsCnt; + + /** */ + public int rebalancingPartitionsCnt; + + /** */ + public long rebalancedKeys; + + /** */ + public long estimatedRebalancingKeys; + + /** */ + public long keysToRebalanceLeft; + + /** */ + public long rebalancingKeysRate; + + /** */ + public long rebalancingBytesRate; + + /** */ + public long rebalanceStartTime; + + /** */ + public long rebalanceFinishTime; + + /** */ + public long rebalanceClearingPartitionsLeft; + + /** */ + public String keyType; + + /** */ + public String valType; + + /** */ + public boolean storeByVal; + + /** */ + public boolean statisticsEnabled; + + /** */ + public boolean managementEnabled; + + /** */ + public boolean readThrough; + + /** */ + public boolean writeThrough; + + /** */ + public boolean validForReading; + + /** */ + public boolean validForWriting; + + /** */ + public String txKeyCollisions; + + /** */ + public boolean idxRebuildInProgress; + + /** */ + public long idxRebuildKeyProcessed; + + /** */ + public int idxBuildPartitionsLeftCount; + + /** {@inheritDoc} */ + @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) { + writer.setBuffer(buf); + + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeLong(cacheGets)) + return false; + + writer.incrementState(); + + case 1: + if (!writer.writeLong(cachePuts)) + return false; + + writer.incrementState(); + + case 2: + if (!writer.writeLong(entryProcessorPuts)) + return false; + + writer.incrementState(); + + case 3: + if (!writer.writeLong(entryProcessorReadOnlyInvocations)) + return false; + + writer.incrementState(); + + case 4: + if (!writer.writeFloat(entryProcessorAverageInvocationTime)) + return false; + + writer.incrementState(); + + case 5: + if (!writer.writeLong(entryProcessorInvocations)) + return false; + + writer.incrementState(); + + case 6: + if (!writer.writeLong(entryProcessorRemovals)) + return false; + + writer.incrementState(); + + case 7: + if (!writer.writeLong(entryProcessorMisses)) + return false; + + writer.incrementState(); + + case 8: + if (!writer.writeLong(entryProcessorHits)) + return false; + + writer.incrementState(); + + case 9: + if (!writer.writeFloat(entryProcessorMissPercentage)) + return false; + + writer.incrementState(); + + case 10: + if (!writer.writeFloat(entryProcessorHitPercentage)) + return false; + + writer.incrementState(); + + case 11: + if (!writer.writeFloat(entryProcessorMaxInvocationTime)) + return false; + + writer.incrementState(); + + case 12: + if (!writer.writeFloat(entryProcessorMinInvocationTime)) + return false; + + writer.incrementState(); + + case 13: + if (!writer.writeLong(cacheHits)) + return false; + + writer.incrementState(); + + case 14: + if (!writer.writeLong(cacheMisses)) + return false; + + writer.incrementState(); + + case 15: + if (!writer.writeLong(cacheTxCommits)) + return false; + + writer.incrementState(); + + case 16: + if (!writer.writeLong(cacheTxRollbacks)) + return false; + + writer.incrementState(); + + case 17: + if (!writer.writeLong(cacheEvictions)) + return false; + + writer.incrementState(); + + case 18: + if (!writer.writeLong(cacheRemovals)) + return false; + + writer.incrementState(); + + case 19: + if (!writer.writeFloat(averagePutTime)) + return false; + + writer.incrementState(); + + case 20: + if (!writer.writeFloat(averageGetTime)) + return false; + + writer.incrementState(); + + case 21: + if (!writer.writeFloat(averageRemoveTime)) + return false; + + writer.incrementState(); + + case 22: + if (!writer.writeFloat(averageTxCommitTime)) + return false; + + writer.incrementState(); + + case 23: + if (!writer.writeFloat(averageTxRollbackTime)) + return false; + + writer.incrementState(); + + case 24: + if (!writer.writeString(cacheName)) + return false; + + writer.incrementState(); + + case 25: + if (!writer.writeLong(offHeapGets)) + return false; + + writer.incrementState(); + + case 26: + if (!writer.writeLong(offHeapPuts)) + return false; + + writer.incrementState(); + + case 27: + if (!writer.writeLong(offHeapRemoves)) + return false; + + writer.incrementState(); + + case 28: + if (!writer.writeLong(offHeapEvicts)) + return false; + + writer.incrementState(); + + case 29: + if (!writer.writeLong(offHeapHits)) + return false; + + writer.incrementState(); + + case 30: + if (!writer.writeLong(offHeapMisses)) + return false; + + writer.incrementState(); + + case 31: + if (!writer.writeLong(offHeapEntriesCnt)) + return false; + + writer.incrementState(); + + case 32: + if (!writer.writeLong(heapEntriesCnt)) + return false; + + writer.incrementState(); + + case 33: + if (!writer.writeLong(offHeapPrimaryEntriesCnt)) + return false; + + writer.incrementState(); + + case 34: + if (!writer.writeLong(offHeapBackupEntriesCnt)) + return false; + + writer.incrementState(); + + case 35: + if (!writer.writeLong(offHeapAllocatedSize)) + return false; + + writer.incrementState(); + + case 36: + if (!writer.writeInt(size)) + return false; + + writer.incrementState(); + + case 37: + if (!writer.writeLong(cacheSize)) + return false; + + writer.incrementState(); + + case 38: + if (!writer.writeInt(keySize)) + return false; + + writer.incrementState(); + + case 39: + if (!writer.writeBoolean(empty)) + return false; + + writer.incrementState(); + + case 40: + if (!writer.writeInt(dhtEvictQueueCurrSize)) + return false; + + writer.incrementState(); + + case 41: + if (!writer.writeInt(txThreadMapSize)) + return false; + + writer.incrementState(); + + case 42: + if (!writer.writeInt(txXidMapSize)) + return false; + + writer.incrementState(); + + case 43: + if (!writer.writeInt(txCommitQueueSize)) + return false; + + writer.incrementState(); + + case 44: + if (!writer.writeInt(txPrepareQueueSize)) + return false; + + writer.incrementState(); + + case 45: + if (!writer.writeInt(txStartVerCountsSize)) + return false; + + writer.incrementState(); + + case 46: + if (!writer.writeInt(txCommittedVersionsSize)) + return false; + + writer.incrementState(); + + case 47: + if (!writer.writeInt(txRolledbackVersionsSize)) + return false; + + writer.incrementState(); + + case 48: + if (!writer.writeInt(txDhtThreadMapSize)) + return false; + + writer.incrementState(); + + case 49: + if (!writer.writeInt(txDhtXidMapSize)) + return false; + + writer.incrementState(); + + case 50: + if (!writer.writeInt(txDhtCommitQueueSize)) + return false; + + writer.incrementState(); + + case 51: + if (!writer.writeInt(txDhtPrepareQueueSize)) + return false; + + writer.incrementState(); + + case 52: + if (!writer.writeInt(txDhtStartVerCountsSize)) + return false; + + writer.incrementState(); + + case 53: + if (!writer.writeInt(txDhtCommittedVersionsSize)) + return false; + + writer.incrementState(); + + case 54: + if (!writer.writeInt(txDhtRolledbackVersionsSize)) + return false; + + writer.incrementState(); + + case 55: + if (!writer.writeBoolean(writeBehindEnabled)) + return false; + + writer.incrementState(); + + case 56: + if (!writer.writeInt(writeBehindFlushSize)) + return false; + + writer.incrementState(); + + case 57: + if (!writer.writeInt(writeBehindFlushThreadCnt)) + return false; + + writer.incrementState(); + + case 58: + if (!writer.writeLong(writeBehindFlushFreq)) + return false; + + writer.incrementState(); + + case 59: + if (!writer.writeInt(writeBehindStoreBatchSize)) + return false; + + writer.incrementState(); + + case 60: + if (!writer.writeInt(writeBehindTotalCriticalOverflowCnt)) + return false; + + writer.incrementState(); + + case 61: + if (!writer.writeInt(writeBehindCriticalOverflowCnt)) + return false; + + writer.incrementState(); + + case 62: + if (!writer.writeInt(writeBehindErrorRetryCnt)) + return false; + + writer.incrementState(); + + case 63: + if (!writer.writeInt(writeBehindBufSize)) + return false; + + writer.incrementState(); + + case 64: + if (!writer.writeInt(totalPartitionsCnt)) + return false; + + writer.incrementState(); + + case 65: + if (!writer.writeInt(rebalancingPartitionsCnt)) + return false; + + writer.incrementState(); + + case 66: + if (!writer.writeLong(rebalancedKeys)) + return false; + + writer.incrementState(); + + case 67: + if (!writer.writeLong(estimatedRebalancingKeys)) + return false; + + writer.incrementState(); + + case 68: + if (!writer.writeLong(keysToRebalanceLeft)) + return false; + + writer.incrementState(); + + case 69: + if (!writer.writeLong(rebalancingKeysRate)) + return false; + + writer.incrementState(); + + case 70: + if (!writer.writeLong(rebalancingBytesRate)) + return false; + + writer.incrementState(); + + case 71: + if (!writer.writeLong(rebalanceStartTime)) + return false; + + writer.incrementState(); + + case 72: + if (!writer.writeLong(rebalanceFinishTime)) + return false; + + writer.incrementState(); + + case 73: + if (!writer.writeLong(rebalanceClearingPartitionsLeft)) + return false; + + writer.incrementState(); + + case 74: + if (!writer.writeString(keyType)) + return false; + + writer.incrementState(); + + case 75: + if (!writer.writeString(valType)) + return false; + + writer.incrementState(); + + case 76: + if (!writer.writeBoolean(storeByVal)) + return false; + + writer.incrementState(); + + case 77: + if (!writer.writeBoolean(statisticsEnabled)) + return false; + + writer.incrementState(); + + case 78: + if (!writer.writeBoolean(managementEnabled)) + return false; + + writer.incrementState(); + + case 79: + if (!writer.writeBoolean(readThrough)) + return false; + + writer.incrementState(); + + case 80: + if (!writer.writeBoolean(writeThrough)) + return false; + + writer.incrementState(); + + case 81: + if (!writer.writeBoolean(validForReading)) + return false; + + writer.incrementState(); + + case 82: + if (!writer.writeBoolean(validForWriting)) + return false; + + writer.incrementState(); + + case 83: + if (!writer.writeString(txKeyCollisions)) + return false; + + writer.incrementState(); + + case 84: + if (!writer.writeBoolean(idxRebuildInProgress)) + return false; + + writer.incrementState(); + + case 85: + if (!writer.writeLong(idxRebuildKeyProcessed)) + return false; + + writer.incrementState(); + + case 86: + if (!writer.writeInt(idxBuildPartitionsLeftCount)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** {@inheritDoc} */ + @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) { + reader.setBuffer(buf); + + switch (reader.state()) { + case 0: + cacheGets = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 1: + cachePuts = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 2: + entryProcessorPuts = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 3: + entryProcessorReadOnlyInvocations = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 4: + entryProcessorAverageInvocationTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 5: + entryProcessorInvocations = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 6: + entryProcessorRemovals = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 7: + entryProcessorMisses = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 8: + entryProcessorHits = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 9: + entryProcessorMissPercentage = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 10: + entryProcessorHitPercentage = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 11: + entryProcessorMaxInvocationTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 12: + entryProcessorMinInvocationTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 13: + cacheHits = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 14: + cacheMisses = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 15: + cacheTxCommits = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 16: + cacheTxRollbacks = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 17: + cacheEvictions = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 18: + cacheRemovals = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 19: + averagePutTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 20: + averageGetTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 21: + averageRemoveTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 22: + averageTxCommitTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 23: + averageTxRollbackTime = reader.readFloat(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 24: + cacheName = reader.readString(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 25: + offHeapGets = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 26: + offHeapPuts = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 27: + offHeapRemoves = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 28: + offHeapEvicts = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 29: + offHeapHits = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 30: + offHeapMisses = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 31: + offHeapEntriesCnt = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 32: + heapEntriesCnt = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 33: + offHeapPrimaryEntriesCnt = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 34: + offHeapBackupEntriesCnt = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 35: + offHeapAllocatedSize = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 36: + size = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 37: + cacheSize = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 38: + keySize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 39: + empty = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 40: + dhtEvictQueueCurrSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 41: + txThreadMapSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 42: + txXidMapSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 43: + txCommitQueueSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 44: + txPrepareQueueSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 45: + txStartVerCountsSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 46: + txCommittedVersionsSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 47: + txRolledbackVersionsSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 48: + txDhtThreadMapSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 49: + txDhtXidMapSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 50: + txDhtCommitQueueSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 51: + txDhtPrepareQueueSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 52: + txDhtStartVerCountsSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 53: + txDhtCommittedVersionsSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 54: + txDhtRolledbackVersionsSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 55: + writeBehindEnabled = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 56: + writeBehindFlushSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 57: + writeBehindFlushThreadCnt = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 58: + writeBehindFlushFreq = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 59: + writeBehindStoreBatchSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 60: + writeBehindTotalCriticalOverflowCnt = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 61: + writeBehindCriticalOverflowCnt = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 62: + writeBehindErrorRetryCnt = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 63: + writeBehindBufSize = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 64: + totalPartitionsCnt = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 65: + rebalancingPartitionsCnt = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 66: + rebalancedKeys = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 67: + estimatedRebalancingKeys = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 68: + keysToRebalanceLeft = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 69: + rebalancingKeysRate = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 70: + rebalancingBytesRate = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 71: + rebalanceStartTime = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 72: + rebalanceFinishTime = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 73: + rebalanceClearingPartitionsLeft = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 74: + keyType = reader.readString(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 75: + valType = reader.readString(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 76: + storeByVal = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 77: + statisticsEnabled = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 78: + managementEnabled = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 79: + readThrough = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 80: + writeThrough = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 81: + validForReading = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 82: + validForWriting = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 83: + txKeyCollisions = reader.readString(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 84: + idxRebuildInProgress = reader.readBoolean(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 85: + idxRebuildKeyProcessed = reader.readLong(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + + case 86: + idxBuildPartitionsLeftCount = reader.readInt(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } + + /** {@inheritDoc} */ + @Override public short directType() { + return 136; + } +} diff --git a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/LegacyNodeIdMessage.java b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/LegacyNodeIdMessage.java new file mode 100644 index 0000000000000..9901added476b --- /dev/null +++ b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/communication/LegacyNodeIdMessage.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.benchmarks.jmh.communication; + +import java.nio.ByteBuffer; +import java.util.UUID; +import org.apache.ignite.plugin.extensions.communication.Message; +import org.apache.ignite.plugin.extensions.communication.MessageReader; +import org.apache.ignite.plugin.extensions.communication.MessageWriter; + +/** + * Legacy version of {@code NodeIdMessage} with inline {@code writeTo}/{@code readFrom} + * methods (the old code-generated approach). Used for benchmarking against the new + * {@code MessageSerializer}-based approach. + * + *
Contains a single {@link UUID} field — the minimal possible message. + */ +public class LegacyNodeIdMessage implements Message { + /** */ + public UUID nodeId; + + /** */ + public LegacyNodeIdMessage() { + // No-op. + } + + /** */ + public LegacyNodeIdMessage(UUID nodeId) { + this.nodeId = nodeId; + } + + /** {@inheritDoc} */ + @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) { + writer.setBuffer(buf); + + if (!writer.isHeaderWritten()) { + if (!writer.writeHeader(directType())) + return false; + + writer.onHeaderWritten(); + } + + switch (writer.state()) { + case 0: + if (!writer.writeUuid(nodeId)) + return false; + + writer.incrementState(); + } + + return true; + } + + /** {@inheritDoc} */ + @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) { + reader.setBuffer(buf); + + switch (reader.state()) { + case 0: + nodeId = reader.readUuid(); + + if (!reader.isLastRead()) + return false; + + reader.incrementState(); + } + + return true; + } + + /** {@inheritDoc} */ + @Override public short directType() { + return -1; + } +} diff --git a/modules/benchmarks/src/test/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhCacheMetricsSerializationBenchmarkTest.java b/modules/benchmarks/src/test/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhCacheMetricsSerializationBenchmarkTest.java new file mode 100644 index 0000000000000..3243286a901d0 --- /dev/null +++ b/modules/benchmarks/src/test/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhCacheMetricsSerializationBenchmarkTest.java @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.benchmarks.jmh.communication; + +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.ignite.internal.processors.cluster.CacheMetricsMessage; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Correctness test for {@link JmhCacheMetricsSerializationBenchmark}. + * + *
Verifies that both the new (MessageSerializer) and legacy (inline writeTo/readFrom) + * approaches produce identical round-trip results, and that all benchmark methods + * complete without errors. + */ +public class JmhCacheMetricsSerializationBenchmarkTest { + /** */ + private JmhCacheMetricsSerializationBenchmark benchmark; + + /** */ + @Before + public void setUp() throws Exception { + benchmark = new JmhCacheMetricsSerializationBenchmark(); + benchmark.setup(); + } + + /** New writeTo must complete in a single call. */ + @Test + public void testNewWriteToCompletes() { + assertTrue("newWriteTo must return true", benchmark.newWriteTo()); + } + + /** New readFrom must complete in a single call. */ + @Test + public void testNewReadFromCompletes() { + assertTrue("newReadFrom must return true", benchmark.newReadFrom()); + } + + /** Legacy writeTo must complete in a single call. */ + @Test + public void testLegacyWriteToCompletes() { + assertTrue("legacyWriteTo must return true", benchmark.legacyWriteTo()); + } + + /** Legacy readFrom must complete in a single call. */ + @Test + public void testLegacyReadFromCompletes() { + assertTrue("legacyReadFrom must return true", benchmark.legacyReadFrom()); + } + + /** Round-trip for new approach preserves all fields. */ + @Test + public void testNewRoundTripPreservesFields() throws Exception { + assertTrue(benchmark.newWriteTo()); + assertTrue(benchmark.newReadFrom()); + + var src = (CacheMetricsMessage)FieldUtils.readField(benchmark, "newMsg", true); + var dst = (CacheMetricsMessage)FieldUtils.readField(benchmark, "newReadTarget", true); + + assertCacheMetricsEqual(src, dst); + } + + /** Round-trip for legacy approach preserves all fields. */ + @Test + public void testLegacyRoundTripPreservesFields() throws Exception { + assertTrue(benchmark.legacyWriteTo()); + assertTrue(benchmark.legacyReadFrom()); + + var src = (LegacyCacheMetricsMessage)FieldUtils.readField(benchmark, "legacyMsg", true); + var dst = (LegacyCacheMetricsMessage)FieldUtils.readField(benchmark, "legacyReadTarget", true); + + assertLegacyCacheMetricsEqual(src, dst); + } + + // ----- helpers ----- + + /** Asserts all 87 fields of {@link CacheMetricsMessage} are equal. */ + private static void assertCacheMetricsEqual(CacheMetricsMessage src, CacheMetricsMessage dst) { + assertEquals("cacheGets", src.cacheGets, dst.cacheGets); + assertEquals("cachePuts", src.cachePuts, dst.cachePuts); + assertEquals("entryProcessorPuts", src.entryProcessorPuts, dst.entryProcessorPuts); + assertEquals("entryProcessorReadOnlyInvocations", src.entryProcessorReadOnlyInvocations, dst.entryProcessorReadOnlyInvocations); + assertEquals("entryProcessorAverageInvocationTime", + src.entryProcessorAverageInvocationTime, dst.entryProcessorAverageInvocationTime, 0.0f); + assertEquals("entryProcessorInvocations", src.entryProcessorInvocations, dst.entryProcessorInvocations); + assertEquals("entryProcessorRemovals", src.entryProcessorRemovals, dst.entryProcessorRemovals); + assertEquals("entryProcessorMisses", src.entryProcessorMisses, dst.entryProcessorMisses); + assertEquals("entryProcessorHits", src.entryProcessorHits, dst.entryProcessorHits); + assertEquals("entryProcessorMissPercentage", + src.entryProcessorMissPercentage, dst.entryProcessorMissPercentage, 0.0f); + assertEquals("entryProcessorHitPercentage", + src.entryProcessorHitPercentage, dst.entryProcessorHitPercentage, 0.0f); + assertEquals("entryProcessorMaxInvocationTime", src.entryProcessorMaxInvocationTime, dst.entryProcessorMaxInvocationTime, 0.0f); + assertEquals("entryProcessorMinInvocationTime", src.entryProcessorMinInvocationTime, dst.entryProcessorMinInvocationTime, 0.0f); + assertEquals("cacheHits", src.cacheHits, dst.cacheHits); + assertEquals("cacheMisses", src.cacheMisses, dst.cacheMisses); + assertEquals("cacheTxCommits", src.cacheTxCommits, dst.cacheTxCommits); + assertEquals("cacheTxRollbacks", src.cacheTxRollbacks, dst.cacheTxRollbacks); + assertEquals("cacheEvictions", src.cacheEvictions, dst.cacheEvictions); + assertEquals("cacheRemovals", src.cacheRemovals, dst.cacheRemovals); + assertEquals("averagePutTime", src.averagePutTime, dst.averagePutTime, 0.0f); + assertEquals("averageGetTime", src.averageGetTime, dst.averageGetTime, 0.0f); + assertEquals("averageRemoveTime", src.averageRemoveTime, dst.averageRemoveTime, 0.0f); + assertEquals("averageTxCommitTime", src.averageTxCommitTime, dst.averageTxCommitTime, 0.0f); + assertEquals("averageTxRollbackTime", src.averageTxRollbackTime, dst.averageTxRollbackTime, 0.0f); + assertEquals("cacheName", src.cacheName, dst.cacheName); + assertEquals("offHeapGets", src.offHeapGets, dst.offHeapGets); + assertEquals("offHeapPuts", src.offHeapPuts, dst.offHeapPuts); + assertEquals("offHeapRemoves", src.offHeapRemoves, dst.offHeapRemoves); + assertEquals("offHeapEvicts", src.offHeapEvicts, dst.offHeapEvicts); + assertEquals("offHeapHits", src.offHeapHits, dst.offHeapHits); + assertEquals("offHeapMisses", src.offHeapMisses, dst.offHeapMisses); + assertEquals("offHeapEntriesCnt", src.offHeapEntriesCnt, dst.offHeapEntriesCnt); + assertEquals("heapEntriesCnt", src.heapEntriesCnt, dst.heapEntriesCnt); + assertEquals("offHeapPrimaryEntriesCnt", src.offHeapPrimaryEntriesCnt, dst.offHeapPrimaryEntriesCnt); + assertEquals("offHeapBackupEntriesCnt", src.offHeapBackupEntriesCnt, dst.offHeapBackupEntriesCnt); + assertEquals("offHeapAllocatedSize", src.offHeapAllocatedSize, dst.offHeapAllocatedSize); + assertEquals("size", src.size, dst.size); + assertEquals("cacheSize", src.cacheSize, dst.cacheSize); + assertEquals("keySize", src.keySize, dst.keySize); + assertEquals("empty", src.empty, dst.empty); + assertEquals("dhtEvictQueueCurrSize", src.dhtEvictQueueCurrSize, dst.dhtEvictQueueCurrSize); + assertEquals("txThreadMapSize", src.txThreadMapSize, dst.txThreadMapSize); + assertEquals("txXidMapSize", src.txXidMapSize, dst.txXidMapSize); + assertEquals("txCommitQueueSize", src.txCommitQueueSize, dst.txCommitQueueSize); + assertEquals("txPrepareQueueSize", src.txPrepareQueueSize, dst.txPrepareQueueSize); + assertEquals("txStartVerCountsSize", src.txStartVerCountsSize, dst.txStartVerCountsSize); + assertEquals("txCommittedVersionsSize", src.txCommittedVersionsSize, dst.txCommittedVersionsSize); + assertEquals("txRolledbackVersionsSize", src.txRolledbackVersionsSize, dst.txRolledbackVersionsSize); + assertEquals("txDhtThreadMapSize", src.txDhtThreadMapSize, dst.txDhtThreadMapSize); + assertEquals("txDhtXidMapSize", src.txDhtXidMapSize, dst.txDhtXidMapSize); + assertEquals("txDhtCommitQueueSize", src.txDhtCommitQueueSize, dst.txDhtCommitQueueSize); + assertEquals("txDhtPrepareQueueSize", src.txDhtPrepareQueueSize, dst.txDhtPrepareQueueSize); + assertEquals("txDhtStartVerCountsSize", src.txDhtStartVerCountsSize, dst.txDhtStartVerCountsSize); + assertEquals("txDhtCommittedVersionsSize", src.txDhtCommittedVersionsSize, dst.txDhtCommittedVersionsSize); + assertEquals("txDhtRolledbackVersionsSize", src.txDhtRolledbackVersionsSize, dst.txDhtRolledbackVersionsSize); + assertEquals("writeBehindEnabled", src.writeBehindEnabled, dst.writeBehindEnabled); + assertEquals("writeBehindFlushSize", src.writeBehindFlushSize, dst.writeBehindFlushSize); + assertEquals("writeBehindFlushThreadCnt", src.writeBehindFlushThreadCnt, dst.writeBehindFlushThreadCnt); + assertEquals("writeBehindFlushFreq", src.writeBehindFlushFreq, dst.writeBehindFlushFreq); + assertEquals("writeBehindStoreBatchSize", src.writeBehindStoreBatchSize, dst.writeBehindStoreBatchSize); + assertEquals("writeBehindTotalCriticalOverflowCnt", + src.writeBehindTotalCriticalOverflowCnt, dst.writeBehindTotalCriticalOverflowCnt); + assertEquals("writeBehindCriticalOverflowCnt", src.writeBehindCriticalOverflowCnt, dst.writeBehindCriticalOverflowCnt); + assertEquals("writeBehindErrorRetryCnt", src.writeBehindErrorRetryCnt, dst.writeBehindErrorRetryCnt); + assertEquals("writeBehindBufSize", src.writeBehindBufSize, dst.writeBehindBufSize); + assertEquals("totalPartitionsCnt", src.totalPartitionsCnt, dst.totalPartitionsCnt); + assertEquals("rebalancingPartitionsCnt", src.rebalancingPartitionsCnt, dst.rebalancingPartitionsCnt); + assertEquals("rebalancedKeys", src.rebalancedKeys, dst.rebalancedKeys); + assertEquals("estimatedRebalancingKeys", src.estimatedRebalancingKeys, dst.estimatedRebalancingKeys); + assertEquals("keysToRebalanceLeft", src.keysToRebalanceLeft, dst.keysToRebalanceLeft); + assertEquals("rebalancingKeysRate", src.rebalancingKeysRate, dst.rebalancingKeysRate); + assertEquals("rebalancingBytesRate", src.rebalancingBytesRate, dst.rebalancingBytesRate); + assertEquals("rebalanceStartTime", src.rebalanceStartTime, dst.rebalanceStartTime); + assertEquals("rebalanceFinishTime", src.rebalanceFinishTime, dst.rebalanceFinishTime); + assertEquals("rebalanceClearingPartitionsLeft", src.rebalanceClearingPartitionsLeft, dst.rebalanceClearingPartitionsLeft); + assertEquals("keyType", src.keyType, dst.keyType); + assertEquals("valType", src.valType, dst.valType); + assertEquals("storeByVal", src.storeByVal, dst.storeByVal); + assertEquals("statisticsEnabled", src.statisticsEnabled, dst.statisticsEnabled); + assertEquals("managementEnabled", src.managementEnabled, dst.managementEnabled); + assertEquals("readThrough", src.readThrough, dst.readThrough); + assertEquals("writeThrough", src.writeThrough, dst.writeThrough); + assertEquals("validForReading", src.validForReading, dst.validForReading); + assertEquals("validForWriting", src.validForWriting, dst.validForWriting); + assertEquals("txKeyCollisions", src.txKeyCollisions, dst.txKeyCollisions); + assertEquals("idxRebuildInProgress", src.idxRebuildInProgress, dst.idxRebuildInProgress); + assertEquals("idxRebuildKeyProcessed", src.idxRebuildKeyProcessed, dst.idxRebuildKeyProcessed); + assertEquals("idxBuildPartitionsLeftCount", src.idxBuildPartitionsLeftCount, dst.idxBuildPartitionsLeftCount); + } + + /** Asserts all 87 fields of {@link LegacyCacheMetricsMessage} are equal. */ + private static void assertLegacyCacheMetricsEqual(LegacyCacheMetricsMessage src, LegacyCacheMetricsMessage dst) { + assertEquals("cacheGets", src.cacheGets, dst.cacheGets); + assertEquals("cachePuts", src.cachePuts, dst.cachePuts); + assertEquals("entryProcessorPuts", src.entryProcessorPuts, dst.entryProcessorPuts); + assertEquals("entryProcessorReadOnlyInvocations", + src.entryProcessorReadOnlyInvocations, dst.entryProcessorReadOnlyInvocations); + assertEquals("entryProcessorAverageInvocationTime", + src.entryProcessorAverageInvocationTime, dst.entryProcessorAverageInvocationTime, 0.0f); + assertEquals("entryProcessorInvocations", src.entryProcessorInvocations, dst.entryProcessorInvocations); + assertEquals("entryProcessorRemovals", src.entryProcessorRemovals, dst.entryProcessorRemovals); + assertEquals("entryProcessorMisses", src.entryProcessorMisses, dst.entryProcessorMisses); + assertEquals("entryProcessorHits", src.entryProcessorHits, dst.entryProcessorHits); + assertEquals("cacheName", src.cacheName, dst.cacheName); + assertEquals("size", src.size, dst.size); + assertEquals("cacheSize", src.cacheSize, dst.cacheSize); + assertEquals("keySize", src.keySize, dst.keySize); + assertEquals("empty", src.empty, dst.empty); + assertEquals("writeBehindEnabled", src.writeBehindEnabled, dst.writeBehindEnabled); + assertEquals("keyType", src.keyType, dst.keyType); + assertEquals("valType", src.valType, dst.valType); + assertEquals("txKeyCollisions", src.txKeyCollisions, dst.txKeyCollisions); + assertEquals("idxRebuildInProgress", src.idxRebuildInProgress, dst.idxRebuildInProgress); + assertEquals("idxRebuildKeyProcessed", src.idxRebuildKeyProcessed, dst.idxRebuildKeyProcessed); + assertEquals("idxBuildPartitionsLeftCount", src.idxBuildPartitionsLeftCount, dst.idxBuildPartitionsLeftCount); + } +} diff --git a/modules/benchmarks/src/test/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhNodeIdSerializationBenchmarkTest.java b/modules/benchmarks/src/test/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhNodeIdSerializationBenchmarkTest.java new file mode 100644 index 0000000000000..29a58f72968ff --- /dev/null +++ b/modules/benchmarks/src/test/java/org/apache/ignite/internal/benchmarks/jmh/communication/JmhNodeIdSerializationBenchmarkTest.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.benchmarks.jmh.communication; + +import org.apache.commons.lang3.reflect.FieldUtils; +import org.apache.ignite.spi.communication.tcp.messages.NodeIdMessage; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Correctness test for {@link JmhNodeIdSerializationBenchmark}. + * + *
Verifies that both the new (MessageSerializer) and legacy (inline writeTo/readFrom) + * approaches produce identical round-trip results for the minimal single-field message. + */ +public class JmhNodeIdSerializationBenchmarkTest { + /** */ + private JmhNodeIdSerializationBenchmark benchmark; + + /** */ + @Before + public void setUp() throws Exception { + benchmark = new JmhNodeIdSerializationBenchmark(); + benchmark.setup(); + } + + /** New writeTo must complete in a single call. */ + @Test + public void testNewWriteToCompletes() { + assertTrue("newWriteTo must return true", benchmark.newWriteTo()); + } + + /** New readFrom must complete in a single call. */ + @Test + public void testNewReadFromCompletes() { + assertTrue("newReadFrom must return true", benchmark.newReadFrom()); + } + + /** Legacy writeTo must complete in a single call. */ + @Test + public void testLegacyWriteToCompletes() { + assertTrue("legacyWriteTo must return true", benchmark.legacyWriteTo()); + } + + /** Legacy readFrom must complete in a single call. */ + @Test + public void testLegacyReadFromCompletes() { + assertTrue("legacyReadFrom must return true", benchmark.legacyReadFrom()); + } + + /** Round-trip for new approach preserves the UUID field. */ + @Test + public void testNewRoundTripPreservesField() throws Exception { + assertTrue(benchmark.newWriteTo()); + assertTrue(benchmark.newReadFrom()); + + var src = (NodeIdMessage)FieldUtils.readField(benchmark, "newMsg", true); + var dst = (NodeIdMessage)FieldUtils.readField(benchmark, "newReadTarget", true); + + assertNotNull("readTarget must not be null after readFrom", dst); + assertEquals("nodeId", src.nodeId(), dst.nodeId()); + } + + /** Round-trip for legacy approach preserves the UUID field. */ + @Test + public void testLegacyRoundTripPreservesField() throws Exception { + assertTrue(benchmark.legacyWriteTo()); + assertTrue(benchmark.legacyReadFrom()); + + var src = (LegacyNodeIdMessage)FieldUtils.readField(benchmark, "legacyMsg", true); + var dst = (LegacyNodeIdMessage)FieldUtils.readField(benchmark, "legacyReadTarget", true); + + assertNotNull("readTarget must not be null after readFrom", dst); + assertEquals("nodeId", src.nodeId, dst.nodeId); + } +}