Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ public class Binary implements Comparable<Binary>, Serializable {

private final byte[] values;

private int hash;

// indicate whether hash has been calculated
private boolean hasCalculatedHash;

private String stringCache;

/** if the bytes v is modified, the modification is visible to this binary. */
public Binary(byte[] v) {
this.values = v;
Expand Down Expand Up @@ -94,11 +87,7 @@ public boolean equals(Object other) {

@Override
public int hashCode() {
if (!hasCalculatedHash) {
hash = Arrays.hashCode(values);
hasCalculatedHash = true;
}
return hash;
return Arrays.hashCode(values);
}

/**
Expand All @@ -121,10 +110,7 @@ public String getStringValue() {
if (values == null) {
return null;
}
if (stringCache == null) {
stringCache = new String(this.values, STRING_CHARSET);
}
return stringCache;
return new String(this.values, STRING_CHARSET);
}

public String getTextEncodingType() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.iotdb.pipe.api.type;

import org.junit.Assert;
import org.junit.Test;

public class BinaryTest {

@Test
public void hashCodeUsesCurrentValues() {
byte[] values = new byte[] {'a'};
Binary binary = new Binary(values);
binary.hashCode();
binary.getStringValue();

values[0] = 'b';
Binary sameBinary = new Binary(new byte[] {'b'});

Assert.assertEquals(binary, sameBinary);
Assert.assertEquals(binary.hashCode(), sameBinary.hashCode());
Assert.assertEquals("b", binary.getStringValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(status, statusReason, loadScore);
return Objects.hash(status, statusReason);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.iotdb.confignode.manager.load.cache.node;

import org.apache.iotdb.commons.cluster.NodeStatus;

import org.junit.Assert;
import org.junit.Test;

public class NodeStatisticsTest {

@Test
public void hashCodeMatchesEqualsWhenOnlyLoadScoreDiffers() {
NodeStatistics lowLoadStatistics = new NodeStatistics(1, NodeStatus.Running, null, 1);
NodeStatistics highLoadStatistics = new NodeStatistics(2, NodeStatus.Running, null, 2);

Assert.assertEquals(lowLoadStatistics, highLoadStatistics);
Assert.assertEquals(lowLoadStatistics.hashCode(), highLoadStatistics.hashCode());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import org.apache.iotdb.db.storageengine.dataregion.memtable.IMemTable;
import org.apache.iotdb.db.storageengine.dataregion.memtable.PrimitiveMemTable;
import org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALMode;
import org.apache.iotdb.db.storageengine.dataregion.wal.utils.listener.AbstractResultListener.Status;
import org.apache.iotdb.db.storageengine.dataregion.wal.utils.listener.WALFlushListener;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.db.utils.constant.TestConstant;

Expand All @@ -40,7 +42,6 @@
import org.apache.tsfile.utils.Binary;
import org.apache.tsfile.utils.BitMap;
import org.apache.tsfile.write.schema.MeasurementSchema;
import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -55,6 +56,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand All @@ -72,16 +74,19 @@ public class WALNodeWaitForRollFileTest {
private String prevConsensus;
private WALNode walNode;
private long originWALThreshold;
private long originWalSyncModeFsyncDelayInMs;

@Before
public void setUp() throws Exception {
originWALThreshold = config.getWalFileSizeThresholdInByte();
originWalSyncModeFsyncDelayInMs = config.getWalSyncModeFsyncDelayInMs();
EnvironmentUtils.cleanDir(logDirectory);
prevMode = config.getWalMode();
prevConsensus = config.getDataRegionConsensusProtocolClass();
config.setWalMode(WALMode.SYNC);
config.setDataRegionConsensusProtocolClass(ConsensusFactory.IOT_CONSENSUS);
config.setWalFileSizeThresholdInByte(2 * 1024 * 1024);
config.setWalSyncModeFsyncDelayInMs(3);
walNode = new WALNode(identifier, logDirectory);
}

Expand All @@ -91,6 +96,7 @@ public void tearDown() throws Exception {
config.setWalMode(prevMode);
config.setDataRegionConsensusProtocolClass(prevConsensus);
config.setWalFileSizeThresholdInByte(originWALThreshold);
config.setWalSyncModeFsyncDelayInMs(originWalSyncModeFsyncDelayInMs);
EnvironmentUtils.cleanDir(logDirectory);
StorageEngine.getInstance().reset();
}
Expand All @@ -116,20 +122,20 @@ public void testWaitForNextReadyTimesOutWhenNoData() throws Exception {
* requires a WAL file roll. This is the core behavioral change: the old waitForFlush would return
* on any buffer sync, but waitForRollFile only returns when a new WAL file is created.
*/
@Test
@Test(timeout = 30000)
public void testWaitForNextReadyNotWokenByFlushWithoutRoll() throws Exception {
IMemTable memTable = new PrimitiveMemTable(databasePath, dataRegionId);
walNode.onMemTableCreated(memTable, logDirectory + File.separator + "test.tsfile");

// write a small amount of data (not enough to trigger roll)
InsertTabletNode insertTabletNode = getInsertTabletNode(devicePath, new long[] {1});
insertTabletNode.setSearchIndex(1);
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));

Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());
WALFlushListener flushListener =
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));
assertEquals(Status.SUCCESS, flushListener.waitForResult());

// data is flushed to buffer but no WAL file roll happened yet, iterator at search index 1
// should not find data (because the current-writing WAL file is not readable by the iterator)
Expand All @@ -151,34 +157,35 @@ public void testWaitForNextReadyNotWokenByFlushWithoutRoll() throws Exception {
* Verifies that waitForNextReady succeeds after a WAL file roll makes data readable. The iterator
* should wake up when rollLogWriter signals the rollLogWriterCondition.
*/
@Test
@Test(timeout = 30000)
public void testWaitForNextReadySucceedsAfterRollFile() throws Exception {
IMemTable memTable = new PrimitiveMemTable(databasePath, dataRegionId);
walNode.onMemTableCreated(memTable, logDirectory + File.separator + "test.tsfile");

WALFlushListener lastFlushListener = null;
// write data with search index
for (int i = 1; i <= 5; i++) {
InsertTabletNode insertTabletNode = getInsertTabletNode(devicePath, new long[] {i});
insertTabletNode.setSearchIndex(i);
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));
lastFlushListener =
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));
}

Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());
assertNotNull(lastFlushListener);
assertEquals(Status.SUCCESS, lastFlushListener.waitForResult());

// roll the WAL file so the data is in a closed file readable by the iterator
walNode.rollWALFile();
Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());

// iterator at search index 1 should find the data after roll
ConsensusReqReader.ReqIterator iterator = walNode.getReqIterator(1);
assertTrue(iterator.hasNext());
assertNotNull(iterator.next());
}

@Test
@Test(timeout = 30000)
public void testLegacySeparatorStillWorksAfterRollFile() throws Exception {
IMemTable memTable = new PrimitiveMemTable(databasePath, dataRegionId);
walNode.onMemTableCreated(memTable, logDirectory + File.separator + "test.tsfile");
Expand All @@ -189,12 +196,11 @@ public void testLegacySeparatorStillWorksAfterRollFile() throws Exception {
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));
walNode.log(memTable.getMemTableId(), new ContinuousSameSearchIndexSeparatorNode());

Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());
WALFlushListener separatorFlushListener =
walNode.log(memTable.getMemTableId(), new ContinuousSameSearchIndexSeparatorNode());
assertEquals(Status.SUCCESS, separatorFlushListener.waitForResult());

walNode.rollWALFile();
Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());

ConsensusReqReader.ReqIterator iterator = walNode.getReqIterator(1);
assertTrue(iterator.hasNext());
Expand All @@ -214,12 +220,12 @@ public void testWaitForNextReadyWakesUpOnConcurrentRoll() throws Exception {
InsertTabletNode insertTabletNode = getInsertTabletNode(devicePath, new long[] {1});
insertTabletNode.setSearchIndex(1);
insertTabletNode.setLastFragment(true);
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));

Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());
WALFlushListener flushListener =
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));
assertEquals(Status.SUCCESS, flushListener.waitForResult());

ConsensusReqReader.ReqIterator iterator = walNode.getReqIterator(1);

Expand All @@ -246,7 +252,6 @@ public void testWaitForNextReadyWakesUpOnConcurrentRoll() throws Exception {

// trigger WAL file roll — this should signal rollLogWriterCondition and wake up the iterator
walNode.rollWALFile();
Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());

waitFuture.get(20, TimeUnit.SECONDS);
executor.shutdown();
Expand Down Expand Up @@ -274,14 +279,12 @@ public void testWaitForNextReadyWithAutoRollOnSizeThreshold() throws Exception {
// write initial data with search index
InsertTabletNode first = getInsertTabletNode(devicePath, new long[] {1});
first.setSearchIndex(1);
walNode.log(
memTable.getMemTableId(),
first,
Collections.singletonList(new int[] {0, first.getRowCount()}));

Awaitility.await()
.atMost(10, TimeUnit.SECONDS)
.until(() -> walNode.isAllWALEntriesConsumed());
WALFlushListener flushListener =
walNode.log(
memTable.getMemTableId(),
first,
Collections.singletonList(new int[] {0, first.getRowCount()}));
assertEquals(Status.SUCCESS, flushListener.waitForResult());

ConsensusReqReader.ReqIterator iterator = walNode.getReqIterator(1);

Expand Down Expand Up @@ -341,12 +344,12 @@ public void testWaitForNextReadyAutoTriggersRollOnTimeout() throws Exception {
InsertTabletNode insertTabletNode = getInsertTabletNode(devicePath, new long[] {1});
insertTabletNode.setSearchIndex(1);
insertTabletNode.setLastFragment(true);
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));

Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> walNode.isAllWALEntriesConsumed());
WALFlushListener flushListener =
walNode.log(
memTable.getMemTableId(),
insertTabletNode,
Collections.singletonList(new int[] {0, insertTabletNode.getRowCount()}));
assertEquals(Status.SUCCESS, flushListener.waitForResult());

// iterator cannot read the active WAL file, so hasNext() should be false
ConsensusReqReader.ReqIterator iterator = walNode.getReqIterator(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,12 @@ public boolean equals(Object o) {
return false;
}
MetaInfo that = (MetaInfo) o;
if (tagNames == null || that.tagNames == null) {
return false;
}
for (String tagName : that.tagNames) {
if (!tagNames.contains(tagName)) {
return false;
}
}
return true;
return type == that.type && Objects.equals(tagNames, that.tagNames);
}

@Override
public int hashCode() {
return Objects.hash(tagNames);
return Objects.hash(type, tagNames);
}

@Override
Expand Down
Loading
Loading