diff options
| author | Keith Packard <keithp@keithp.com> | 2015-07-11 19:11:48 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2015-07-11 19:11:48 -0700 | 
| commit | 1b6f3de0a547fa452d5c40775bcf59c49b229e5e (patch) | |
| tree | e4e89dd9c228f3fe83b8952d94de8ad217f9c48a | |
| parent | b313a5a3d5aba89330c0e20eeac00cc571828953 (diff) | |
altoslib: Limit simultanous map tile downloads to 128
Before this change, every tile requested would get downloaded at the
same time. With moving to distance-based offline map loading radius
values, the number of tiles at closer zooms was in the thousands,
overwhelming the network.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | altoslib/AltosMapStore.java | 90 | 
1 files changed, 63 insertions, 27 deletions
| diff --git a/altoslib/AltosMapStore.java b/altoslib/AltosMapStore.java index 88412593..a10a1665 100644 --- a/altoslib/AltosMapStore.java +++ b/altoslib/AltosMapStore.java @@ -118,49 +118,85 @@ public class AltosMapStore {  	static final long	forbidden_interval = 60l * 1000l * 1000l * 1000l;  	static final long 	google_maps_ratelimit_ms = 1200; +	static Object	loader_lock = new Object(); + +	static LinkedList<AltosMapStore> waiting = new LinkedList<AltosMapStore>(); +	static LinkedList<AltosMapStore> running = new LinkedList<AltosMapStore>(); + +	static final int concurrent_loaders = 128; + +	static void start_loaders() { +		while (!waiting.isEmpty() && running.size() < concurrent_loaders) { +			AltosMapStore 	s = waiting.remove(); +			running.add(s); +			Thread lt = s.make_loader_thread(); +			lt.start(); +		} +	} + +	void finish_loader() { +		synchronized(loader_lock) { +			running.remove(this); +			start_loaders(); +		} +	} + +	void add_loader() { +		synchronized(loader_lock) { +			waiting.add(this); +			start_loaders(); +		} +	} +  	class loader implements Runnable {  		public void run() { -			if (file.exists()) { -				notify_listeners(AltosMapTile.success); -				return; -			} - -			synchronized(forbidden_lock) { -				if (forbidden_set && (System.nanoTime() - forbidden_time) < forbidden_interval) { -					notify_listeners(AltosMapTile.forbidden); +			try { +				if (file.exists()) { +					notify_listeners(AltosMapTile.success);  					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.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(); +								}  							}  						}  					} +				} else { +					new_status = fetch_url();  				} -			} else { -				new_status = fetch_url(); +				notify_listeners(new_status); +			} finally { +				finish_loader();  			} -			notify_listeners(new_status);  		}  	} +	private Thread make_loader_thread() { +		return new Thread(new loader()); +	} +  	private void load() { -		loader	l = new loader(); -		Thread	lt = new Thread(l); -		lt.start(); +		add_loader();  	}  	private AltosMapStore (String url, File file) { | 
