Issue #1096 fix memory leaks in CcfpResource
Change-Id: Icccd4d3811327b9a1dcfdf6a5a2cc714ff92afbc Former-commit-id:7b62f6ac75
[formerly73f428e4d5
] [formerly047441f91c
[formerly 5e9d7763442ab91cb8d33c16139eb5bca9b033ea]] Former-commit-id:047441f91c
Former-commit-id:347c13143b
This commit is contained in:
parent
3b41cd02f4
commit
0cc8e95b0c
2 changed files with 105 additions and 43 deletions
|
@ -24,6 +24,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ import com.vividsolutions.jts.geom.Point;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Sep 22, 2009 3072 bsteffen Initial creation
|
* Sep 22, 2009 3072 bsteffen Initial creation
|
||||||
|
* Aug 23, 2012 1096 njensen Fixed memory leaks
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -161,8 +163,10 @@ public class CcfpResource extends
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disposeFrames() {
|
private void disposeFrames() {
|
||||||
for (DisplayFrame frame : frames.values()) {
|
synchronized (frames) {
|
||||||
frame.dispose();
|
for (DisplayFrame frame : frames.values()) {
|
||||||
|
frame.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,11 +184,15 @@ public class CcfpResource extends
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String inspect(ReferencedCoordinate coord) throws VizException {
|
public String inspect(ReferencedCoordinate coord) throws VizException {
|
||||||
if (frames.get(this.displayedDataTime) == null) {
|
DisplayFrame frame = null;
|
||||||
|
synchronized (frames) {
|
||||||
|
frame = frames.get(this.displayedDataTime);
|
||||||
|
}
|
||||||
|
if (frame == null) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
StringBuilder res = new StringBuilder();
|
StringBuilder res = new StringBuilder();
|
||||||
for (CcfpRecord record : frames.get(this.displayedDataTime).records) {
|
for (CcfpRecord record : frame.records) {
|
||||||
// Check if we have an area we are rendering
|
// Check if we have an area we are rendering
|
||||||
if (isPaintingArea(record)) {
|
if (isPaintingArea(record)) {
|
||||||
try {
|
try {
|
||||||
|
@ -216,15 +224,20 @@ public class CcfpResource extends
|
||||||
*/
|
*/
|
||||||
private void updateRecords(IGraphicsTarget target,
|
private void updateRecords(IGraphicsTarget target,
|
||||||
PaintProperties paintProps) throws VizException {
|
PaintProperties paintProps) throws VizException {
|
||||||
DisplayFrame frame = frames.get(this.displayedDataTime);
|
DisplayFrame frame = null;
|
||||||
if (frame == null) {
|
synchronized (frames) {
|
||||||
frame = new DisplayFrame();
|
frame = frames.get(this.displayedDataTime);
|
||||||
frames.put(this.displayedDataTime, frame);
|
if (frame == null) {
|
||||||
|
frame = new DisplayFrame();
|
||||||
|
frames.put(this.displayedDataTime, frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the new Records
|
// Add all the new Records
|
||||||
Collection<CcfpRecord> newRecords = unprocessedRecords
|
Collection<CcfpRecord> newRecords = null;
|
||||||
.get(this.displayedDataTime);
|
synchronized (unprocessedRecords) {
|
||||||
|
newRecords = unprocessedRecords.get(this.displayedDataTime);
|
||||||
|
}
|
||||||
for (CcfpRecord record : newRecords) {
|
for (CcfpRecord record : newRecords) {
|
||||||
// If we need to draw anything for this record then keep it
|
// If we need to draw anything for this record then keep it
|
||||||
if (isPaintingArea(record) || isPaintingMovement(record)
|
if (isPaintingArea(record) || isPaintingMovement(record)
|
||||||
|
@ -259,14 +272,19 @@ public class CcfpResource extends
|
||||||
this.displayedDataTime = paintProps.getDataTime();
|
this.displayedDataTime = paintProps.getDataTime();
|
||||||
|
|
||||||
// First check to see if we need to process new data
|
// First check to see if we need to process new data
|
||||||
Collection<CcfpRecord> unprocessed = unprocessedRecords
|
Collection<CcfpRecord> unprocessed = null;
|
||||||
.get(this.displayedDataTime);
|
synchronized (unprocessedRecords) {
|
||||||
|
unprocessed = unprocessedRecords.get(this.displayedDataTime);
|
||||||
|
}
|
||||||
if (unprocessed != null && unprocessed.size() > 0) {
|
if (unprocessed != null && unprocessed.size() > 0) {
|
||||||
updateRecords(target, paintProps);
|
updateRecords(target, paintProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hopefully we now have some data to display, if not bail
|
// Hopefully we now have some data to display, if not bail
|
||||||
DisplayFrame frame = frames.get(this.displayedDataTime);
|
DisplayFrame frame = null;
|
||||||
|
synchronized (frames) {
|
||||||
|
frame = frames.get(this.displayedDataTime);
|
||||||
|
}
|
||||||
if (frame == null) {
|
if (frame == null) {
|
||||||
this.displayedDataTime = null;
|
this.displayedDataTime = null;
|
||||||
return;
|
return;
|
||||||
|
@ -509,14 +527,24 @@ public class CcfpResource extends
|
||||||
*/
|
*/
|
||||||
protected void addRecord(CcfpRecord obj) {
|
protected void addRecord(CcfpRecord obj) {
|
||||||
DataTime dataTime = obj.getDataTime();
|
DataTime dataTime = obj.getDataTime();
|
||||||
Collection<CcfpRecord> records = unprocessedRecords.get(dataTime);
|
if (resourceData.durationMatches(dataTime)) {
|
||||||
if (records == null) {
|
Collection<CcfpRecord> records = null;
|
||||||
records = new ArrayList<CcfpRecord>();
|
boolean brandNew = false;
|
||||||
unprocessedRecords.put(dataTime, records);
|
synchronized (unprocessedRecords) {
|
||||||
this.dataTimes.add(dataTime);
|
records = unprocessedRecords.get(dataTime);
|
||||||
Collections.sort(this.dataTimes);
|
if (records == null) {
|
||||||
|
records = new HashSet<CcfpRecord>();
|
||||||
|
unprocessedRecords.put(dataTime, records);
|
||||||
|
brandNew = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (brandNew) {
|
||||||
|
this.dataTimes.add(dataTime);
|
||||||
|
Collections.sort(this.dataTimes);
|
||||||
|
}
|
||||||
|
|
||||||
|
records.add(obj);
|
||||||
}
|
}
|
||||||
records.add(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -677,16 +705,40 @@ public class CcfpResource extends
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void project(CoordinateReferenceSystem crs) throws VizException {
|
public void project(CoordinateReferenceSystem crs) throws VizException {
|
||||||
disposeFrames();
|
synchronized (frames) {
|
||||||
// add as unprocessed to make sure frames created
|
disposeFrames();
|
||||||
for (DataTime time : frames.keySet()) {
|
// add as unprocessed to make sure frames created
|
||||||
DisplayFrame frame = frames.get(time);
|
for (DataTime time : frames.keySet()) {
|
||||||
if (frame != null) {
|
DisplayFrame frame = frames.get(time);
|
||||||
List<CcfpRecord> copyList = new ArrayList<CcfpRecord>(
|
if (frame != null) {
|
||||||
frame.records);
|
List<CcfpRecord> copyList = new ArrayList<CcfpRecord>(
|
||||||
unprocessedRecords.put(time, copyList);
|
frame.records);
|
||||||
|
synchronized (unprocessedRecords) {
|
||||||
|
unprocessedRecords.put(time, copyList);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(DataTime time) {
|
||||||
|
super.remove(time);
|
||||||
|
Collection<CcfpRecord> notNeeded = null;
|
||||||
|
synchronized (unprocessedRecords) {
|
||||||
|
notNeeded = unprocessedRecords.remove(time);
|
||||||
|
}
|
||||||
|
if (notNeeded != null) {
|
||||||
|
notNeeded.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayFrame frame = null;
|
||||||
|
synchronized (frames) {
|
||||||
|
frame = frames.remove(time);
|
||||||
|
}
|
||||||
|
if (frame != null) {
|
||||||
|
frame.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,10 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
import com.raytheon.uf.viz.ccfp.Activator;
|
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData;
|
import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
import com.raytheon.uf.viz.core.status.StatusConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -56,8 +54,9 @@ import com.raytheon.uf.viz.core.status.StatusConstants;
|
||||||
*/
|
*/
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
public class CcfpResourceData extends AbstractRequestableResourceData {
|
public class CcfpResourceData extends AbstractRequestableResourceData {
|
||||||
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(CcfpResourceData.class);
|
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(CcfpResourceData.class);
|
||||||
|
|
||||||
// This flag determnies if we draw lines and polygons
|
// This flag determnies if we draw lines and polygons
|
||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
private boolean displayArea = true;
|
private boolean displayArea = true;
|
||||||
|
@ -69,35 +68,34 @@ public class CcfpResourceData extends AbstractRequestableResourceData {
|
||||||
// This flag determines if we display text boxes
|
// This flag determines if we display text boxes
|
||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
private boolean displayText = true;
|
private boolean displayText = true;
|
||||||
|
|
||||||
// Filter by coverage
|
// Filter by coverage
|
||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
private int coverageFilter = 0;
|
private int coverageFilter = 0;
|
||||||
|
|
||||||
|
|
||||||
@XmlAttribute
|
@XmlAttribute
|
||||||
private int validDuration = 0;
|
private int validDuration = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!super.equals(obj)) {
|
if (!super.equals(obj)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj instanceof CcfpResourceData == false) {
|
if (obj instanceof CcfpResourceData == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CcfpResourceData other = (CcfpResourceData) obj;
|
CcfpResourceData other = (CcfpResourceData) obj;
|
||||||
|
|
||||||
if (other.coverageFilter != this.coverageFilter) {
|
if (other.coverageFilter != this.coverageFilter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other.validDuration != this.validDuration) {
|
if (other.validDuration != this.validDuration) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other.displayText != this.displayText) {
|
if (other.displayText != this.displayText) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +107,7 @@ public class CcfpResourceData extends AbstractRequestableResourceData {
|
||||||
if (other.displayMovement != this.displayMovement) {
|
if (other.displayMovement != this.displayMovement) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +120,7 @@ public class CcfpResourceData extends AbstractRequestableResourceData {
|
||||||
DataTime[] originalTimes = super.getAvailableTimes();
|
DataTime[] originalTimes = super.getAvailableTimes();
|
||||||
ArrayList<DataTime> newTimes = new ArrayList<DataTime>();
|
ArrayList<DataTime> newTimes = new ArrayList<DataTime>();
|
||||||
for (DataTime time : originalTimes) {
|
for (DataTime time : originalTimes) {
|
||||||
if (time.getValidPeriod().getDuration() == validDuration * 1000) {
|
if (durationMatches(time)) {
|
||||||
newTimes.add(time);
|
newTimes.add(time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +145,18 @@ public class CcfpResourceData extends AbstractRequestableResourceData {
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a DataTime's valid period matches the duration of the resource
|
||||||
|
* data
|
||||||
|
*
|
||||||
|
* @param time
|
||||||
|
* the time to check
|
||||||
|
* @return true if the durations are equal, otherwise false
|
||||||
|
*/
|
||||||
|
protected boolean durationMatches(DataTime time) {
|
||||||
|
return time.getValidPeriod().getDuration() == validDuration * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isDisplayArea() {
|
public boolean isDisplayArea() {
|
||||||
return displayArea;
|
return displayArea;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +195,6 @@ public class CcfpResourceData extends AbstractRequestableResourceData {
|
||||||
|
|
||||||
public void setValidDuration(int validDuration) {
|
public void setValidDuration(int validDuration) {
|
||||||
this.validDuration = validDuration;
|
this.validDuration = validDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue