net.openhft.chronicle.queue.impl.single.MicroToucher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of chronicle-queue Show documentation
Show all versions of chronicle-queue Show documentation
Java library for persisted low latency messaging (Java 8+)
/*
* Copyright 2016-2022 chronicle.software
*
* https://chronicle.software
*
* Licensed 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 net.openhft.chronicle.queue.impl.single;
import net.openhft.chronicle.bytes.Bytes;
import net.openhft.chronicle.bytes.BytesStore;
import net.openhft.chronicle.wire.Wire;
import net.openhft.posix.MSyncFlag;
import net.openhft.posix.PosixAPI;
public class MicroToucher {
private final StoreAppender appender;
private long lastPageTouched = 0;
private volatile long lastPageToSync = 0;
private long lastPageSynced = 0;
public MicroToucher(StoreAppender appender) {
this.appender = appender;
}
public boolean execute() {
final Wire bufferWire = appender.wire();
if (bufferWire == null)
return false;
final long lastPosition = appender.lastPosition;
final long lastPage = lastPosition & ~0xFFF;
final long nextPage = (lastPosition + 0xFFF) & ~0xFFF;
Bytes> bytes = bufferWire.bytes();
if (nextPage != lastPageTouched) {
lastPageTouched = nextPage;
try {
// best effort
final BytesStore, ?> bs = bytes.bytesStore();
if (bs.inside(nextPage, 8))
touchPage(nextPage, bs);
} catch (Throwable ignored) {
}
return true;
}
lastPageToSync = lastPage;
return false;
}
public void bgExecute() {
final long lastPage = this.lastPageToSync;
final long start = this.lastPageSynced;
final long length = Math.min(8 << 20, lastPage - start);
// System.out.println("len "+length);
if (length < 8 << 20)
return;
final Wire bufferWire = appender.wire();
if (bufferWire == null)
return;
BytesStore, ?> bytes = bufferWire.bytes().bytesStore();
sync(bytes, start, length);
this.lastPageSynced += length;
}
private void sync(BytesStore, ?> bytes, long start, long length) {
if (!bytes.inside(start, length))
return;
// long a = System.nanoTime();
PosixAPI.posix().msync(bytes.addressForRead(start), length, MSyncFlag.MS_ASYNC);
// System.out.println("sync took " + (System.nanoTime() - a) / 1000);
}
protected boolean touchPage(long nextPage, BytesStore, ?> bs) {
return bs.compareAndSwapLong(nextPage, 0, 0);
}
}