SampleType
- type that is implemented by all samples that are passed to this
sample decimator and that is also implemented by the sample
generated by this sample decimator. Typically, this is the sample
type used by the control-system support that provides the
implementation of this interface.public interface SampleDecimator<SampleType extends Sample>
Stateful utility that decimates samples. The sample decimator is responsible
for generating decimated samples when one or more decimation levels exist for
a channel. For each decimated sample that is going to be generated, a new
sample decimator is created by calling the control-system support's
createSampleDecimator
method.
Unlike most components provided by a control-system support, the sample decimator does not have to be thread-safe. The archiver creates a new sample decimator for each decimated sample that is supposed to be generated and only uses this sample decimator from a single thread.
The methods provided by this interface must not block or perform any long-running actions because they might be called from time-sensitive threads.
The contract between the archiver and the control-system support specifies that the sample decimator is used in the following way and order:
ControlSystemSupport.createSampleDecimator(String, java.util.Map, long, long)
.processSample(Sample)
method is called
with a sample that has a time stamp less than or equal to the start time of
the interval. This way, the sample decimator always knows the channel's state
right from the beginning of the interval.processSample(Sample)
method is called for each additional
sample that is present in the interval. The samples are passed in the order
of their time-stamps.buildDecimatedSample()
method is called.getDecimatedSample()
and
getDecimatedSampleEstimatedSize()
methods to get the generated
decimated sample and its estimated size. After that, the sample decimator is
not used any longer.
The samples passed to processSample(Sample)
may be raw samples (that
were received from the control-system support through a
SampleListener
). However, they may also be decimated samples if the
channel has several decimation levels and the decimated sample for such a
level is supposed to be generated. In this case, the samples passed to this
sample decimator may be decimated samples from a decimation level with a
shorter decimation period. The archiver may only use samples from another
decimation level instead of raw samples when the decimation periods are
compatible, meaning that the decimation period of the decimation for which
this decimator is supposed to generate a sample is an integer multiple of the
decimation period of the decimation level of the samples that are passed.
The sample returned by the getDecimatedSample()
method must always
have a time stamp that is equal to the interval start-time that was specified
when the sample decimator was created. Returning a sample with a different
time-stamp is considered an error.
The actual implementation of how samples are decimated can vary significantly between different control-system supports or even depend on the internal sample type and thus on the channel or the channel's configuration. For example, a simple implementation might always choose the sample right at the beginning of the period, thus simply decimating the samples. A more complex implementation might calculate the average of all samples and create a decimated sample that represents this average, possibly carrying additional information like minimum and maximum values or the standard deviation.
Implementations that use a different strategy for generating decimated samples depending on the channel's configuration should consider that typically, decimated samples are generated and stored over a prolonged period. If the configuration is changed within this period, the strategy for generating the decimated samples might also change, leading to a situation in which some of the decimated samples have been generated using one algorithm and other decimated samples have been generated using a different algorithm. It is completely legal for a control-system support to exhibit such behavior, but in this case it also has to be able to deal with such data when processing samples.
Modifier and Type | Method and Description |
---|---|
void |
buildDecimatedSample()
Builds the decimated sample.
|
String |
getChannelName()
Returns the name of the channel for which this sample decimator decimates
samples.
|
SampleType |
getDecimatedSample()
Returns the decimated sample that has been generated by
buildDecimatedSample() . |
int |
getDecimatedSampleEstimatedSize()
Returns the estimated size of the decimated sample.
|
long |
getIntervalLength()
Returns the length of the period for which this sample decimator
generates a decimated sample.
|
long |
getIntervalStartTime()
Returns the start time of the period for which this sample decimator
generated a decimated sample.
|
void |
processSample(SampleType sample)
Processes a sample, updating the internal state with the information from
the sample.
|
void buildDecimatedSample()
processSample(Sample)
has been called at least once. It must be
called before calling getDecimatedSample()
or
getDecimatedSampleEstimatedSize()
.
processSample(Sample)
must not be called again after calling
this method and this method must only be called once. This method may
throw an IllegalStateException
if the specified call order is
violated. However, there is no guarantee that such an exception is
thrown.String getChannelName()
SampleType getDecimatedSample()
buildDecimatedSample()
. This sample has the time stamp of the
interval start as specified by getIntervalStartTime()
. This
method must only be called after calling buildDecimatedSample()
.
This method may throw an IllegalStateException
if the specified
call order is violated. However, there is no guarantee that such an
exception is thrown.processSample(Sample)
.int getDecimatedSampleEstimatedSize()
Returns the estimated size of the decimated sample. This is the size that the sample is expected to have when it is serialized into the database. The size is specified in bytes.
This information is used by the archiving code to keep track of the total size of the samples that are stored inside a bucket. As storing too much (or too little) data in a single bucket has an impact on performance, the archiving code will decide to start a new bucket when a certain size has been reached. Therefore, this estimate should be as accurate as possible.
This method must only be called after calling
buildDecimatedSample()
. This method may throw an
IllegalStateException
if the specified call order is violated.
However, there is no guarantee that such an exception is thrown.
getDecimatedSample()
) in bytes.long getIntervalLength()
Returns the length of the period for which this sample decimator generates a decimated sample. The length is specified in nanoseconds. The returned length is the length that was specified when this sample decimator was created.
The period covered by this sample decimator is specified by the interval [start time, start + length).
long getIntervalStartTime()
Returns the start time of the period for which this sample decimator generated a decimated sample. The start time is specified as the number of nanoseconds since epoch (January 1st, 1970, 00:00:00 UTC). The returned start time is the time that was specified when this sample decimator was created.
The period covered by this sample decimator is specified by the interval [start time, start + length).
void processSample(SampleType sample)
Processes a sample, updating the internal state with the information from
the sample. This method must be called for every sample that is is in the
interval specified by the start time and length (as returned by
getIntervalStartTime()
and getIntervalLength()
).
The first sample passed to this method must have a time stamp that is
less than or equal to the interval start-time. This method must be called
at least once before calling buildDecimatedSample()
. It must not
be called after calling buildDecimatedSample()
. This method may
throw an IllegalStateException
if the specified call order is
violated. However, there is no guarantee that such an exception is
thrown.
sample
- sample that shall be processed, updating the sample
decimator's internal state.Copyright © 2011–2019 aquenos GmbH. All rights reserved.