/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.util; /** * @author tag * @version $Id$ */ public class AbsentResourceList { // Absent resources: A resource is deemed absent if a specified maximum number of attempts have been made to retrieve it. // Retrieval attempts are governed by a minimum time interval between successive attempts. If an attempt is made // within this interval, the resource is still deemed to be absent until the interval expires. private static final int DEFAULT_MAX_ABSENT_RESOURCE_TRIES = 2; private static final int DEFAULT_MIN_ABSENT_RESOURCE_CHECK_INTERVAL = 10000; private int maxTries = DEFAULT_MAX_ABSENT_RESOURCE_TRIES; private int minCheckInterval = DEFAULT_MIN_ABSENT_RESOURCE_CHECK_INTERVAL; private static class AbsentResoureEntry { long timeOfLastMark; // meant to be the time of the most recent attempt to find the resource int numTries; } private final java.util.concurrent.ConcurrentHashMap<Long, AbsentResoureEntry> possiblyAbsent = new java.util.concurrent.ConcurrentHashMap<Long, AbsentResoureEntry>(); private java.util.SortedSet<Long> definitelyAbsent = java.util.Collections.synchronizedSortedSet( new java.util.TreeSet<Long>()); public AbsentResourceList() { } public AbsentResourceList(int maxTries, int minCheckInterval) { this.maxTries = Math.max(maxTries, 1); this.minCheckInterval = Math.max(minCheckInterval, 500); } public final void markResourceAbsent(long resourceID) { if (this.definitelyAbsent.contains(resourceID)) return; AbsentResoureEntry entry = this.possiblyAbsent.get(resourceID); if (entry == null) this.possiblyAbsent.put(resourceID, entry = new AbsentResoureEntry()); ++entry.numTries; entry.timeOfLastMark = System.currentTimeMillis(); if (entry.numTries >= this.maxTries) { this.definitelyAbsent.add(resourceID); this.possiblyAbsent.remove(resourceID); // entry can now be garbage collected } } public final boolean isResourceAbsent(long resourceID) { if (this.definitelyAbsent.contains(resourceID)) return true; AbsentResoureEntry entry = this.possiblyAbsent.get(resourceID); //noinspection SimplifiableIfStatement if (entry == null) return false; return (System.currentTimeMillis() - entry.timeOfLastMark) < this.minCheckInterval; } public final void unmarkResourceAbsent(long resourceID) { this.definitelyAbsent.remove(resourceID); this.possiblyAbsent.remove(resourceID); } }