use of io.questdb.std.str.Path in project questdb by bluestreak01.
the class TxnScoreboardTest method testLimits.
@Test
public void testLimits() throws Exception {
TestUtils.assertMemoryLeak(() -> {
int expect = 2048;
try (final Path shmPath = new Path()) {
try (TxnScoreboard scoreboard2 = new TxnScoreboard(FilesFacadeImpl.INSTANCE, shmPath.of(root), expect)) {
try (TxnScoreboard scoreboard1 = new TxnScoreboard(FilesFacadeImpl.INSTANCE, shmPath.of(root), expect)) {
// we should successfully acquire expected number of entries
for (int i = 0; i < expect; i++) {
scoreboard1.acquireTxn(i + 134);
}
// and we should be refused to acquire any more slots
try {
scoreboard1.acquireTxn(expect + 134);
Assert.fail();
} catch (CairoException ignored) {
}
// now we release middle slot, this does not free any more slots
scoreboard1.releaseTxn(11 + 134);
Assert.assertEquals(134, scoreboard1.getMin());
// we should NOT be able to allocate more slots
try {
scoreboard1.acquireTxn(expect + 134);
Assert.fail();
} catch (CairoException ignored) {
}
// now that we release "head" slot we should be able to acquire more
scoreboard1.releaseTxn(134);
Assert.assertEquals(135, scoreboard1.getMin());
// and we should be able to allocate another one
scoreboard1.acquireTxn(expect + 134);
// now check that all counts are intact
for (int i = 1; i <= expect; i++) {
if (i != 11) {
Assert.assertEquals(1, scoreboard1.getActiveReaderCount(i + 134));
} else {
Assert.assertEquals(0, scoreboard1.getActiveReaderCount(i + 134));
}
}
}
for (int i = 1; i <= expect; i++) {
if (i != 11) {
Assert.assertEquals(1, scoreboard2.getActiveReaderCount(i + 134));
} else {
Assert.assertEquals(0, scoreboard2.getActiveReaderCount(i + 134));
}
}
}
}
});
}
use of io.questdb.std.str.Path in project questdb by bluestreak01.
the class TxnScoreboardTest method testCleanOnExclusiveOpen.
@Test
public void testCleanOnExclusiveOpen() throws Exception {
TestUtils.assertMemoryLeak(() -> {
try (final Path shmPath = new Path()) {
try (final TxnScoreboard scoreboard = new TxnScoreboard(FilesFacadeImpl.INSTANCE, shmPath.of(root), 1024)) {
for (int i = 0; i < 1500; i++) {
scoreboard.acquireTxn(i);
scoreboard.releaseTxn(i);
}
Assert.assertEquals(1499, scoreboard.getMin());
}
// second open is exclusive, file should be truncated
try (final TxnScoreboard scoreboard2 = new TxnScoreboard(FilesFacadeImpl.INSTANCE, shmPath.of(root), 2048)) {
Assert.assertEquals(0, scoreboard2.getMin());
}
}
});
}
use of io.questdb.std.str.Path in project questdb by bluestreak01.
the class TxnScoreboardTest method testStressOpenParallel.
@Test
public void testStressOpenParallel() throws Exception {
TestUtils.assertMemoryLeak(() -> {
int parallel = 16;
int iterations = (int) 1E3;
SOCountDownLatch latch = new SOCountDownLatch(parallel);
AtomicInteger errors = new AtomicInteger();
for (int i = 0; i < parallel; i++) {
new Thread(() -> {
try (final Path shmPath = new Path()) {
for (int j = 0; j < iterations; j++) {
// noinspection EmptyTryBlock
try (TxnScoreboard ignored = new TxnScoreboard(FilesFacadeImpl.INSTANCE, shmPath.of(root), 1024)) {
// empty body because we need to close this
} catch (Exception ex) {
ex.printStackTrace();
errors.incrementAndGet();
break;
}
}
}
latch.countDown();
}).start();
}
latch.await();
Assert.assertEquals(0, errors.get());
});
}
use of io.questdb.std.str.Path in project questdb by bluestreak01.
the class TxnScoreboardTest method testCleanOnExclusiveOpenLocksFile.
@Test
public void testCleanOnExclusiveOpenLocksFile() throws Exception {
TestUtils.assertMemoryLeak(() -> {
try (final Path shmPath = new Path()) {
FilesFacade ff = FilesFacadeImpl.INSTANCE;
try (final TxnScoreboard scoreboard = new TxnScoreboard(ff, shmPath.of(root), 1024)) {
for (int i = 0; i < 1500; i++) {
scoreboard.acquireTxn(i);
scoreboard.releaseTxn(i);
}
Assert.assertEquals(1499, scoreboard.getMin());
}
// second open is exclusive, file should be truncated
try (final TxnScoreboard scoreboard2 = new TxnScoreboard(ff, shmPath.of(root), 2048)) {
Assert.assertEquals(0, scoreboard2.getMin());
for (int i = 0; i < 10; i++) {
scoreboard2.acquireTxn(i);
scoreboard2.releaseTxn(i);
}
// This should not obtain exclusive lock even though file was empty when scoreboard2 put shared lock
try (final TxnScoreboard scoreboard3 = new TxnScoreboard(ff, shmPath.of(root), 2048)) {
Assert.assertEquals(9, scoreboard2.getMin());
Assert.assertEquals(9, scoreboard3.getMin());
}
}
}
});
}
use of io.questdb.std.str.Path in project questdb by bluestreak01.
the class WriteAndReadSyncTest method testVanilla.
@Test
public void testVanilla() throws IOException, BrokenBarrierException, InterruptedException {
final long longsPerPage = Files.PAGE_SIZE / 8;
for (int loop = 0; loop < 10; loop++) {
Random rnd = new Random();
// increments randomly by [0..512] up to three pages
for (long longCountIncr = longsPerPage, limit = longsPerPage * 3; longCountIncr < limit; longCountIncr += rnd.nextDouble() * 512) {
long longCount = longCountIncr;
final CountDownLatch readLatch = new CountDownLatch(1);
final File file = temp.newFile();
try (Path path = new Path()) {
path.of(file.getAbsolutePath()).$();
FilesFacade ff = FilesFacadeImpl.INSTANCE;
// barrier to make sure both threads kick in at the same time;
final CyclicBarrier barrier = new CyclicBarrier(2);
final AtomicInteger errorCount = new AtomicInteger();
long fd1 = TableUtils.openRW(ff, path, LOG);
long size = longCount * 8 / Files.PAGE_SIZE + 1;
// have this thread write another page
Thread th = new Thread(() -> {
try {
barrier.await();
// over allocate
long mem = TableUtils.mapRW(ff, fd1, (size) * Files.PAGE_SIZE, MemoryTag.NATIVE_DEFAULT);
for (int i = 0; i < longCount; i++) {
Unsafe.getUnsafe().putLong(mem + i * 8L, i);
}
readLatch.countDown();
ff.munmap(mem, (size) * Files.PAGE_SIZE, MemoryTag.NATIVE_DEFAULT);
ff.truncate(mem, longCount * 8);
FilesFacadeImpl.INSTANCE.close(fd1);
} catch (Throwable e) {
errorCount.incrementAndGet();
e.printStackTrace();
}
});
th.start();
barrier.await();
long fd2 = TableUtils.openRO(ff, path, LOG);
try {
readLatch.await();
long mem = TableUtils.mapRO(ff, fd2, longCount * 8, MemoryTag.NATIVE_DEFAULT);
try {
for (int i = 0; i < longCount; i++) {
long value = Unsafe.getUnsafe().getLong(mem + i * 8L);
if (i != value) {
Assert.fail("value " + value + ",offset " + i + ", size " + longCount + ", mapped " + size * Files.PAGE_SIZE);
}
}
} finally {
ff.munmap(mem, longCount * 8, MemoryTag.NATIVE_DEFAULT);
}
} finally {
ff.close(fd2);
}
Assert.assertEquals(0, errorCount.get());
th.join();
}
}
}
}
Aggregations