use of org.apache.ignite.internal.util.Cursor in project ignite-3 by apache.
the class ItMetaStorageServiceTest method testRangeClose.
/**
* Tests {@link MetaStorageService#range(ByteArray, ByteArray, long)}} close.
*
* @throws Exception If failed.
*/
@Test
public void testRangeClose() throws Exception {
ByteArray expKeyFrom = new ByteArray(new byte[] { 1 });
Cursor cursorMock = mock(Cursor.class);
when(mockStorage.range(expKeyFrom.bytes(), null)).thenReturn(cursorMock);
Cursor<Entry> cursor = metaStorageSvc.range(expKeyFrom, null);
cursor.close();
verify(cursorMock, times(1)).close();
}
use of org.apache.ignite.internal.util.Cursor in project ignite-3 by apache.
the class AbstractKeyValueStorageTest method watchCursorForRange.
@Test
public void watchCursorForRange() throws Exception {
byte[] key1 = key(1);
final byte[] val1_1 = keyValue(1, 11);
final byte[] key2 = key(2);
final byte[] val2_1 = keyValue(2, 21);
final byte[] val2_2 = keyValue(2, 22);
final byte[] key3 = key(3);
final byte[] val3_1 = keyValue(3, 31);
assertEquals(0, storage.revision());
assertEquals(0, storage.updateCounter());
// Watch for all updates starting from revision 2.
Cursor<WatchEvent> cur = storage.watch(key1, null, 2);
Iterator<WatchEvent> it = cur.iterator();
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
storage.putAll(List.of(key1, key2), List.of(val1_1, val2_1));
assertEquals(1, storage.revision());
assertEquals(2, storage.updateCounter());
// Revision is less than 2.
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
storage.putAll(List.of(key2, key3), List.of(val2_2, val3_1));
assertEquals(2, storage.revision());
assertEquals(4, storage.updateCounter());
// Revision is 2.
assertTrue(it.hasNext());
WatchEvent watchEvent = it.next();
assertFalse(watchEvent.single());
Map<ByteArray, EntryEvent> map = watchEvent.entryEvents().stream().collect(Collectors.toMap(evt -> new ByteArray(evt.entry().key()), identity()));
assertEquals(2, map.size());
// First update under revision.
EntryEvent e2 = map.get(new ByteArray(key2));
assertNotNull(e2);
Entry oldEntry2 = e2.oldEntry();
assertFalse(oldEntry2.empty());
assertFalse(oldEntry2.tombstone());
assertEquals(1, oldEntry2.revision());
assertEquals(2, oldEntry2.updateCounter());
assertArrayEquals(key2, oldEntry2.key());
assertArrayEquals(val2_1, oldEntry2.value());
Entry newEntry2 = e2.entry();
assertFalse(newEntry2.empty());
assertFalse(newEntry2.tombstone());
assertEquals(2, newEntry2.revision());
assertEquals(3, newEntry2.updateCounter());
assertArrayEquals(key2, newEntry2.key());
assertArrayEquals(val2_2, newEntry2.value());
// Second update under revision.
EntryEvent e3 = map.get(new ByteArray(key3));
assertNotNull(e3);
Entry oldEntry3 = e3.oldEntry();
assertTrue(oldEntry3.empty());
assertFalse(oldEntry3.tombstone());
assertArrayEquals(key3, oldEntry3.key());
Entry newEntry3 = e3.entry();
assertFalse(newEntry3.empty());
assertFalse(newEntry3.tombstone());
assertEquals(2, newEntry3.revision());
assertEquals(4, newEntry3.updateCounter());
assertArrayEquals(key3, newEntry3.key());
assertArrayEquals(val3_1, newEntry3.value());
assertFalse(it.hasNext());
storage.remove(key1);
assertTrue(it.hasNext());
watchEvent = it.next();
assertTrue(watchEvent.single());
EntryEvent e1 = watchEvent.entryEvent();
Entry oldEntry1 = e1.oldEntry();
assertFalse(oldEntry1.empty());
assertFalse(oldEntry1.tombstone());
assertEquals(1, oldEntry1.revision());
assertEquals(1, oldEntry1.updateCounter());
assertArrayEquals(key1, oldEntry1.key());
assertArrayEquals(val1_1, oldEntry1.value());
Entry newEntry1 = e1.entry();
assertFalse(newEntry1.empty());
assertTrue(newEntry1.tombstone());
assertEquals(3, newEntry1.revision());
assertEquals(5, newEntry1.updateCounter());
assertArrayEquals(key1, newEntry1.key());
assertNull(newEntry1.value());
assertFalse(it.hasNext());
cur.close();
}
use of org.apache.ignite.internal.util.Cursor in project ignite-3 by apache.
the class RuntimeSortedIndexTest method test.
@Test
public void test() throws Exception {
IgniteTypeFactory tf = new IgniteTypeFactory();
List<Pair<RelDataType, ImmutableIntList>> testIndexes = Arrays.stream(ROW_TYPES).map(rt -> Pair.of(TypeUtils.createRowType(tf, rt.getKey()), rt.getValue())).collect(Collectors.toList());
for (Pair<RelDataType, ImmutableIntList> testIdx : testIndexes) {
for (int notUnique : NOT_UNIQUE_ROWS_IN_GROUP) {
RuntimeSortedIndex<Object[]> idx0 = generate(testIdx.getKey(), testIdx.getValue(), notUnique);
int rowIdLow = ThreadLocalRandom.current().nextInt(UNIQUE_GROUPS * notUnique);
int rowIdUp = rowIdLow + ThreadLocalRandom.current().nextInt(UNIQUE_GROUPS * notUnique - rowIdLow);
for (int searchNum = 0; searchNum < SEARCH_CNT; ++searchNum) {
Object[] lower = generateFindRow(rowIdLow, testIdx.getKey(), notUnique, testIdx.getValue());
Object[] upper = generateFindRow(rowIdUp, testIdx.getKey(), notUnique, testIdx.getValue());
Cursor<Object[]> cur = idx0.find(lower, upper);
int rows = 0;
while (cur.hasNext()) {
cur.next();
rows++;
}
assertEquals((rowIdUp / notUnique - rowIdLow / notUnique + 1) * notUnique, rows, "Invalid results [rowType=" + testIdx.getKey() + ", notUnique=" + notUnique + ", rowIdLow=" + rowIdLow + ", rowIdUp=" + rowIdUp);
}
}
}
}
use of org.apache.ignite.internal.util.Cursor in project ignite-3 by apache.
the class VersionedRowStore method scan.
/**
* Executes a scan.
*
* @param pred The predicate.
* @return The cursor.
*/
public Cursor<BinaryRow> scan(Predicate<SearchRow> pred) {
Cursor<DataRow> delegate = storage.scan(pred);
// TODO asch add tx support IGNITE-15087.
return new Cursor<BinaryRow>() {
@Nullable
private BinaryRow cur = null;
@Override
public void close() throws Exception {
delegate.close();
}
@NotNull
@Override
public Iterator<BinaryRow> iterator() {
return this;
}
@Override
public boolean hasNext() {
if (cur != null) {
return true;
}
if (delegate.hasNext()) {
DataRow row = delegate.next();
cur = versionedRow(row, null).getFirst();
// Skip tombstones.
return cur != null ? true : hasNext();
}
return false;
}
@Override
public BinaryRow next() {
BinaryRow next = cur;
cur = null;
assert next != null;
return next;
}
};
}
use of org.apache.ignite.internal.util.Cursor in project ignite-3 by apache.
the class ItMetaStorageRaftGroupTest method testRangeNextWorksCorrectlyAfterLeaderChange.
/**
* Tests that {@link MetaStorageService#range(ByteArray, ByteArray, long)}} next command works correctly
* after leader changing.
*
* @throws Exception If failed.
*/
@Test
public void testRangeNextWorksCorrectlyAfterLeaderChange() throws Exception {
final AtomicInteger replicatorStartedCounter = new AtomicInteger(0);
final AtomicInteger replicatorStoppedCounter = new AtomicInteger(0);
when(mockStorage.range(EXPECTED_RESULT_ENTRY1.key().bytes(), new byte[] { 4 })).thenAnswer(invocation -> {
List<org.apache.ignite.internal.metastorage.server.Entry> entries = new ArrayList<>(List.of(EXPECTED_SRV_RESULT_ENTRY1, EXPECTED_SRV_RESULT_ENTRY2));
return new Cursor<org.apache.ignite.internal.metastorage.server.Entry>() {
private final Iterator<org.apache.ignite.internal.metastorage.server.Entry> it = entries.iterator();
@Override
public void close() {
}
@NotNull
@Override
public Iterator<org.apache.ignite.internal.metastorage.server.Entry> iterator() {
return it;
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public org.apache.ignite.internal.metastorage.server.Entry next() {
return it.next();
}
};
});
List<Pair<RaftServer, RaftGroupService>> raftServersRaftGroups = prepareJraftMetaStorages(replicatorStartedCounter, replicatorStoppedCounter);
List<RaftServer> raftServers = raftServersRaftGroups.stream().map(p -> p.key).collect(Collectors.toList());
NetworkAddress oldLeader = raftServersRaftGroups.get(0).value.leader().address();
Optional<RaftServer> oldLeaderServer = raftServers.stream().filter(s -> s.clusterService().topologyService().localMember().address().equals(oldLeader)).findFirst();
// Server that will be alive after we stop leader.
Optional<RaftServer> liveServer = raftServers.stream().filter(s -> !s.clusterService().topologyService().localMember().address().equals(oldLeader)).findFirst();
if (oldLeaderServer.isEmpty() || liveServer.isEmpty()) {
fail();
}
RaftGroupService raftGroupServiceOfLiveServer = raftServersRaftGroups.stream().filter(p -> p.key.equals(liveServer.get())).findFirst().get().value;
MetaStorageService metaStorageSvc = new MetaStorageServiceImpl(raftGroupServiceOfLiveServer, "some_node");
Cursor<Entry> cursor = metaStorageSvc.range(EXPECTED_RESULT_ENTRY1.key(), new ByteArray(new byte[] { 4 }));
assertTrue(TestUtils.waitForCondition(() -> replicatorStartedCounter.get() == 2, 5_000), replicatorStartedCounter.get() + "");
assertTrue(cursor.hasNext());
assertEquals(EXPECTED_RESULT_ENTRY1, (cursor.iterator().next()));
// Ensure that leader has not been changed.
// In a stable topology unexpected leader election shouldn't happen.
assertTrue(TestUtils.waitForCondition(() -> replicatorStartedCounter.get() == 2, 5_000), replicatorStartedCounter.get() + "");
// stop leader
oldLeaderServer.get().stopRaftGroup(METASTORAGE_RAFT_GROUP_NAME);
oldLeaderServer.get().stop();
cluster.stream().filter(c -> c.topologyService().localMember().address().equals(oldLeader)).findFirst().get().stop();
raftGroupServiceOfLiveServer.refreshLeader().get();
assertNotSame(oldLeader, raftGroupServiceOfLiveServer.leader().address());
// ensure that leader has been changed only once
assertTrue(TestUtils.waitForCondition(() -> replicatorStartedCounter.get() == 4, 5_000), replicatorStartedCounter.get() + "");
assertTrue(TestUtils.waitForCondition(() -> replicatorStoppedCounter.get() == 2, 5_000), replicatorStoppedCounter.get() + "");
assertTrue(cursor.hasNext());
assertEquals(EXPECTED_RESULT_ENTRY2, (cursor.iterator().next()));
}
Aggregations