AvroStackSampleSupplier.java
/*
* Copyright 2021 SPF4J.
*
* 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 org.spf4j.stackmonitor;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import org.apache.avro.file.DataFileStream;
import org.apache.avro.specific.SpecificDatumReader;
import org.spf4j.base.avro.ApplicationStackSamples;
import org.spf4j.ssdump2.Converter;
/**
*
* @author Zoltan Farkas
*/
public final class AvroStackSampleSupplier implements StackSampleSupplier {
private Instant from;
private Instant to;
private final Path file;
private final SpecificDatumReader<ApplicationStackSamples> reader;
public AvroStackSampleSupplier(final Path file) {
this.file = file;
this.reader = new SpecificDatumReader<>(ApplicationStackSamples.class);
}
private synchronized void scanLimits() throws IOException {
if (this.from == null) {
Instant lfrom = Instant.MIN;
Instant lto = Instant.MAX;
try (DataFileStream<ApplicationStackSamples> stream
= new DataFileStream<>(Files.newInputStream(file), reader)) {
if (stream.hasNext()) {
ApplicationStackSamples samples = stream.next();
lfrom = samples.getCollectedFrom();
lto = samples.getCollectedTo();
}
while (stream.hasNext()) {
ApplicationStackSamples samples = stream.next();
lto = samples.getCollectedTo();
}
this.from = lfrom;
this.to = lto;
}
}
}
@Override
public synchronized Instant getMin() throws IOException {
scanLimits();
return from;
}
@Override
public synchronized Instant getMax() throws IOException {
scanLimits();
return to;
}
@Override
public ProfileMetaData getMetaData(final Instant pfrom, final Instant pto) throws IOException {
Set<String> contexts = new HashSet<>();
Set<String> tags = new HashSet<>();
try (DataFileStream<ApplicationStackSamples> stream = new DataFileStream<>(Files.newInputStream(file), reader)) {
while (stream.hasNext()) {
ApplicationStackSamples samples = stream.next();
Instant sampleFrom = samples.getCollectedFrom();
Instant sampleTo = samples.getCollectedTo();
if ((sampleFrom.compareTo(sampleTo) == 0
&& sampleFrom.compareTo(pfrom) >= 0 && sampleFrom.compareTo(pfrom) <= 0)
|| (sampleFrom.isBefore(pto) && sampleTo.isAfter(pfrom))) {
contexts.add(samples.getContext());
tags.add(samples.getTag());
}
}
}
return new ProfileMetaData(contexts, tags);
}
@Override
public SampleNode getSamples(final String context, final String tag,
final Instant pfrom, final Instant pto) throws IOException {
SampleNode result = null;
try (DataFileStream<ApplicationStackSamples> stream = new DataFileStream<>(Files.newInputStream(file), reader)) {
while (stream.hasNext()) {
ApplicationStackSamples samples = stream.next();
Instant sampleFrom = samples.getCollectedFrom();
Instant sampleTo = samples.getCollectedTo();
if (((sampleFrom.compareTo(sampleTo) == 0
&& sampleFrom.compareTo(pfrom) >= 0 && sampleFrom.compareTo(pfrom) <= 0)
|| (sampleFrom.isBefore(pto) && sampleTo.isAfter(pfrom)))
&& (tag == null || samples.getTag().equals(tag))
&& (context == null || samples.getContext().equals(context))) {
SampleNode currentSamples = Converter.convert(samples.getStackSamples().iterator());
if (result == null) {
result = currentSamples;
} else if (currentSamples != null) {
result.add(currentSamples);
}
}
}
}
return result;
}
@Override
public String toString() {
return "AvroStackSampleSupplier{file=" + file + '}';
}
}