org.neo4j.internal.collector.RecentQueryBuffer Maven / Gradle / Ivy
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.internal.collector;
import java.util.function.Consumer;
import org.neo4j.kernel.database.NamedDatabaseId;
import org.neo4j.memory.HeapEstimator;
import org.neo4j.memory.MemoryTracker;
import org.neo4j.util.Preconditions;
/**
* Bounded buffer containing meta data about the most recent query invocations across the dbms.
*/
public class RecentQueryBuffer {
private final RingRecentBuffer queries;
private final MemoryTracker memoryTracker;
private static final long SHALLOW_SIZE = HeapEstimator.shallowSizeOfInstance(RecentQueryBuffer.class)
+ HeapEstimator.shallowSizeOfInstance(Consumer.class);
private final int bufferSize;
public RecentQueryBuffer(int maxRecentQueryCount, MemoryTracker memoryTracker) {
this.memoryTracker = memoryTracker;
// Round down to the nearest power of 2
bufferSize = Integer.highestOneBit(maxRecentQueryCount);
queries = new RingRecentBuffer<>(bufferSize, discarded -> memoryTracker.releaseHeap(discarded.estimatedHeap));
if (bufferSize > 0) {
memoryTracker.allocateHeap(queries.estimatedHeapUsage() + SHALLOW_SIZE);
}
}
public long numSilentQueryDrops() {
return queries.numSilentQueryDrops();
}
/**
* Produce a new query into the buffer.
*/
public void produce(TruncatedQuerySnapshot query) {
Preconditions.checkArgument(
query.databaseId != null,
"Only queries targeting a specific database are expected in the recent query buffer.");
if (bufferSize == 0) {
return;
}
memoryTracker.allocateHeap(query.estimatedHeap);
queries.produce(query);
}
/**
* Clear all query meta data for the given database from this buffer.
*/
public void clear(NamedDatabaseId databaseId) {
Preconditions.checkArgument(
databaseId != null,
"Only queries targeting a specific database are expected in the recent query buffer, "
+ "clearing non-database queries will have no effect.");
queries.clearIf(q -> databaseId.equals(q.databaseId));
}
/**
* Apply the consumer on each query in this buffer which targeted the given database.
*/
public void foreach(NamedDatabaseId databaseId, Consumer consumer) {
queries.foreach(q -> {
if (q.databaseId.equals(databaseId)) {
consumer.accept(q);
}
});
}
}