* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-package org.altusmetrum.altoslib_6;
+package org.altusmetrum.altoslib_10;
import java.io.*;
import java.net.*;
public synchronized void add_listener(AltosMapStoreListener listener) {
if (!listeners.contains(listener))
listeners.add(listener);
+ listener.notify_store(this, status);
}
public synchronized void remove_listener(AltosMapStoreListener listener) {
file.delete();
return AltosMapTile.bad_request;
}
- return AltosMapTile.success;
+ return AltosMapTile.fetched;
}
static Object fetch_lock = new Object();
static final long forbidden_interval = 60l * 1000l * 1000l * 1000l;
static final long google_maps_ratelimit_ms = 1200;
- class loader implements Runnable {
+ static Object fetcher_lock = new Object();
- public void run() {
- if (file.exists()) {
- notify_listeners(AltosMapTile.success);
- return;
- }
+ static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>();
+ static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>();
+
+ static final int concurrent_fetchers = 128;
+
+ static void start_fetchers() {
+ while (!waiting.isEmpty() && running.size() < concurrent_fetchers) {
+ AltosMapStore s = waiting.remove();
+ running.add(s);
+ Thread lt = s.make_fetcher_thread();
+ lt.start();
+ }
+ }
+
+ void finish_fetcher() {
+ synchronized(fetcher_lock) {
+ running.remove(this);
+ start_fetchers();
+ }
+ }
+
+ void add_fetcher() {
+ synchronized(fetcher_lock) {
+ waiting.add(this);
+ start_fetchers();
+ }
+ }
+
+ class fetcher implements Runnable {
- synchronized(forbidden_lock) {
- if (forbidden_set && (System.nanoTime() - forbidden_time) < forbidden_interval) {
- notify_listeners(AltosMapTile.forbidden);
+ public void run() {
+ try {
+ if (file.exists()) {
+ notify_listeners(AltosMapTile.fetched);
return;
}
- }
- int new_status;
+ synchronized(forbidden_lock) {
+ if (forbidden_set && (System.nanoTime() - forbidden_time) < forbidden_interval) {
+ notify_listeners(AltosMapTile.forbidden);
+ return;
+ }
+ }
- if (!AltosVersion.has_google_maps_api_key()) {
- synchronized (fetch_lock) {
- long startTime = System.nanoTime();
- new_status = fetch_url();
- if (new_status == AltosMapTile.success) {
- long duration_ms = (System.nanoTime() - startTime) / 1000000;
- if (duration_ms < google_maps_ratelimit_ms) {
- try {
- Thread.sleep(google_maps_ratelimit_ms - duration_ms);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
+ int new_status;
+
+ if (!AltosVersion.has_google_maps_api_key()) {
+ synchronized (fetch_lock) {
+ long startTime = System.nanoTime();
+ new_status = fetch_url();
+ if (new_status == AltosMapTile.fetched) {
+ long duration_ms = (System.nanoTime() - startTime) / 1000000;
+ if (duration_ms < google_maps_ratelimit_ms) {
+ try {
+ Thread.sleep(google_maps_ratelimit_ms - duration_ms);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
}
}
}
+ } else {
+ new_status = fetch_url();
}
- } else {
- new_status = fetch_url();
+ notify_listeners(new_status);
+ } finally {
+ finish_fetcher();
}
- notify_listeners(new_status);
}
}
- private void load() {
- loader l = new loader();
- Thread lt = new Thread(l);
- lt.start();
+ private Thread make_fetcher_thread() {
+ return new Thread(new fetcher());
+ }
+
+ private void fetch() {
+ add_fetcher();
}
private AltosMapStore (String url, File file) {
this.file = file;
if (file.exists())
- status = AltosMapTile.success;
+ status = AltosMapTile.fetched;
else {
- status = AltosMapTile.loading;
- load();
+ status = AltosMapTile.fetching;
+ fetch();
}
}
- public boolean equals(AltosMapStore other) {
+ public int hashCode() {
+ return url.hashCode();
+ }
+
+ public boolean equals(Object o) {
+ if (o == null)
+ return false;
+
+ if (!(o instanceof AltosMapStore))
+ return false;
+
+ AltosMapStore other = (AltosMapStore) o;
return url.equals(other.url);
}