Skip to content

Commit

Permalink
Dispose expired events in AbstractProvider to avoid memory consumption.
Browse files Browse the repository at this point in the history
  • Loading branch information
ktuukkan committed Oct 9, 2021
1 parent 947311e commit 3594598
Showing 1 changed file with 33 additions and 17 deletions.
50 changes: 33 additions & 17 deletions src/main/java/net/sf/marineapi/provider/AbstractProvider.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
/*
/*
* AbstractProvider.java
* Copyright (C) 2011 Kimmo Tuukkanen
*
*
* This file is part of Java Marine API.
* <http://ktuukkan.github.io/marine-api/>
*
*
* Java Marine API is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
*
* Java Marine API 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 Lesser General Public License
* for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with Java Marine API. If not, see <http://www.gnu.org/licenses/>.
*/
Expand All @@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import net.sf.marineapi.nmea.event.SentenceEvent;
import net.sf.marineapi.nmea.event.SentenceListener;
Expand Down Expand Up @@ -56,7 +57,7 @@ public abstract class AbstractProvider<T extends ProviderEvent> implements

/**
* Creates a new instance of AbstractProvider.
*
*
* @param reader Sentence reader to be used as data source
* @param ids Types of sentences to capture for creating provider events
*/
Expand All @@ -69,7 +70,7 @@ public AbstractProvider(SentenceReader reader, String... ids) {

/**
* Creates a new instance of AbstractProvider.
*
*
* @param reader Sentence reader to be used as data source
* @param ids Types of sentences to capture for creating provider events
*/
Expand All @@ -82,7 +83,7 @@ public AbstractProvider(SentenceReader reader, SentenceId... ids) {

/**
* Inserts a listener to provider.
*
*
* @param listener Listener to add
*/
public void addListener(ProviderListener<T> listener) {
Expand All @@ -91,14 +92,14 @@ public void addListener(ProviderListener<T> listener) {

/**
* Creates a {@code ProviderEvent} of type {@code T}.
*
*
* @return Created event, or null if failed.
*/
protected abstract T createProviderEvent();

/**
* Dispatch the TPV event to all listeners.
*
*
* @param event TPVUpdateEvent to dispatch
*/
private void fireProviderEvent(T event) {
Expand All @@ -109,7 +110,7 @@ private void fireProviderEvent(T event) {

/**
* Returns the collected sentences.
*
*
* @return List of sentences.
*/
protected final List<Sentence> getSentences() {
Expand All @@ -122,7 +123,7 @@ protected final List<Sentence> getSentences() {

/**
* Tells if the provider has captured all the specified sentences.
*
*
* @param id Sentence type IDs to look for.
* @return True if all specified IDs match the captured sentences.
*/
Expand All @@ -138,7 +139,7 @@ protected final boolean hasAll(String... id) {
/**
* Tells if the provider has captured at least one of the specified
* sentences.
*
*
* @param id Sentence type IDs to look for, in prioritized order.
* @return True if any of the specified IDs matches the type of at least one
* captured sentences.
Expand All @@ -156,15 +157,15 @@ protected final boolean hasOne(String... id) {
/**
* Tells if provider has captured the required sentences for creating new
* ProviderEvent.
*
*
* @return true if ready to create ProviderEvent, otherwise false.
*/
protected abstract boolean isReady();

/**
* Tells if the captured sentence events contain valid data to be dispatched
* to ProviderListeners.
*
*
* @return true if valid, otherwise false.
*/
protected abstract boolean isValid();
Expand Down Expand Up @@ -196,7 +197,7 @@ public void readingStopped() {

/**
* Removes the specified listener from provider.
*
*
* @param listener Listener to remove
*/
public void removeListener(ProviderListener<T> listener) {
Expand All @@ -210,6 +211,19 @@ private void reset() {
events.clear();
}

/**
* Expunge collected events that are older than {@code timeout} to prevent
* the {@code events} list growing when sentences are being delivered
* without valid data (e.g. during device warm-up or offline state).
*/
private void expunge() {
long now = System.currentTimeMillis();
List<SentenceEvent> expired = this.events.stream()
.filter(event -> now - event.getTimeStamp() > this.timeout)
.collect(Collectors.toList());
this.events.removeAll(expired);
}

/*
* (non-Javadoc)
* @see net.sf.marineapi.nmea.event.SentenceListener#sentenceRead(
Expand All @@ -223,6 +237,8 @@ public void sentenceRead(SentenceEvent event) {
fireProviderEvent(pEvent);
}
reset();
} else {
expunge();
}
}

Expand All @@ -249,7 +265,7 @@ public void setTimeout(int millis) {
* Validates the collected sentences by checking the ages of each sentence
* and then by calling {@link #isValid()}. If extending implementation has
* no validation criteria, it should return always {@code true}.
*
*
* @return true if valid, otherwise false
*/
private boolean validate() {
Expand Down

0 comments on commit 3594598

Please sign in to comment.