All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.skjolber.dc.gtfs.AbstractGtfsChunkedCsvFileEntryHandler Maven / Gradle / Ivy

package com.github.skjolber.dc.gtfs;

import java.util.Map.Entry;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.skjolber.dc.GtfsFeed;
import com.github.skjolber.dc.gtfs.mt.TripAdapter;
import com.github.skjolber.dc.gtfs.st.AgencyAdapter;
import com.github.skjolber.dc.gtfs.st.FeedInfoAdapter;
import com.github.skjolber.dc.gtfs.st.RouteAdapter;
import com.github.skjolber.dc.gtfs.st.StopAdapter;
import com.github.skjolber.dc.gtfs.st.TransferAdapter;
import com.github.skjolber.dc.model.FeedInfo;
import com.github.skjolber.unzip.ChunkedFileEntryHandler;
import com.github.skjolber.unzip.FileEntryStreamHandler;

public abstract class AbstractGtfsChunkedCsvFileEntryHandler implements ChunkedFileEntryHandler {

	private static Logger logger = LoggerFactory.getLogger(AbstractGtfsChunkedCsvFileEntryHandler.class);
	
	protected static final int PARALLEL_BUFFER_SIZE = 16 * 1024 * 1024;
	protected static final int PARALLEL_READ_BUFFER_SIZE = 16 * 1024;
	
	public static int getParallelReadBufferSize() {
		return PARALLEL_READ_BUFFER_SIZE;
	}

	public static int getParallelBufferSize() {
		return PARALLEL_BUFFER_SIZE;
	}

	protected ReentrantLock lock = new ReentrantLock();

	protected GtfsFeed feed = new GtfsFeed();

	protected volatile boolean agency = false;
	protected volatile boolean routes = false;
	protected volatile boolean trips = false;
	protected volatile boolean stops = false;
	protected volatile boolean stopTimes = false;
	protected volatile boolean feedInfo = false;
	protected volatile boolean serviceCalendarDates = false;
	protected volatile boolean serviceCalendar = false;
	protected volatile boolean transfers = false;
	
	protected volatile boolean setAgencyOnRoutes = false;
	protected volatile boolean setRouteOnTrip = false;
	protected volatile boolean setServiceOnTrip = false;
	protected volatile boolean createCalendarServices = false;
	protected volatile boolean createCalendarDatesServices = false;
	protected volatile boolean setStopsOnTransfers = false;

	protected volatile boolean endFileCollectionForFeedInfo = false;
	
	protected StopAdapter stopAdapter;
	protected FeedInfoAdapter feedInfoAdapter = new FeedInfoAdapter();
	protected RouteAdapter routeAdapter = new RouteAdapter(feed);
	protected AgencyAdapter agencyAdapter = new AgencyAdapter();
	protected TripAdapter tripAdapter;
	protected TransferAdapter transferAdapter = new TransferAdapter(feed);
	protected Double stopColocationLimit;


	public AbstractGtfsChunkedCsvFileEntryHandler(int chunkLength, Double colocationLimit) {
		this.stopAdapter = new StopAdapter(feed);
		this.stopColocationLimit = colocationLimit;
	}

	public void setDefaultAgencyId(String defaultAgencyId) {
		feed.setAgencyId(defaultAgencyId);
	}
	
	@Override
	public void beginFileEntry(String name) {
		logger.info("beginFileEntry " + name);
	}

	@Override
	public void beginFileCollection(String name) {
		logger.info("beginFileCollection " + name);
	}

	public void validate() {
		if(!setAgencyOnRoutes) {
			throw new RuntimeException();
		}

		if(!setRouteOnTrip) {
			throw new RuntimeException();
		}
		
		if(!serviceCalendarDates) {
			throw new RuntimeException();
		}
		
		if(!serviceCalendar) {
			throw new RuntimeException();
		}
		
		if(!setServiceOnTrip) {
			throw new RuntimeException();
		}
		
	}

	public void endFileEntry(String name, ThreadPoolExecutor executor) {
		logger.info("End file entry processing " + name);

		switch(name) {
			case "agency.txt" : onAgencyEntryProcessed(executor); break;
			case "routes.txt": onRoutesEntryProcessed(executor); break;
			case "trips.txt": onTripsEntryProcessed(executor); break;
			case "stops.txt": onStopsEntryProcessed(executor); break;
			case "stop_times.txt": onStopTimesEntryProcessed(executor); break;
			case "feed_info.txt": onFeedInfoEntryProcessed(executor); break;
			case "calendar_dates.txt": onCalendarDatesEntryProcessed(executor); break;
			case "calendar.txt": onCalendarEntryProcessed(executor); break;			
			case "transfers.txt": onTransfersEntryProcessed(executor); break;			
		}
		
		// compete for lock to forward state
        if(lock.tryLock()) {
        	try {
        		while(onPostProcessing());
            } finally {
                lock.unlock();
            }
        }
	}

	private void onTransfersEntryProcessed(ThreadPoolExecutor executor) {
		this.transfers = true;
	}

	protected void onFeedInfoEntryProcessed(ThreadPoolExecutor executor) {
		// add to store and lookup cache
		for (Entry entry : feedInfoAdapter.getFeedInfoById().entrySet()) {
			setDefaultAgencyId(entry.getKey());
		}
		
		this.feedInfo = true;
	}

	protected void onStopTimesEntryProcessed(ThreadPoolExecutor executor) {
		// add to store
		this.stopTimes = true;
	}

	protected void onStopsEntryProcessed(ThreadPoolExecutor executor) {
		// add to store and lookup cache
		feed.addStops(stopAdapter.getStops());

		stopAdapter.resolveParents();

		if(stopColocationLimit != null) {
			stopAdapter.resolveColocations(stopColocationLimit, stopColocationLimit);
			feed.addStops(stopAdapter.getParentStops());
		}
		
		this.stops = true;
	}

	protected void onTripsEntryProcessed(ThreadPoolExecutor executor) {
		// add to store and lookup cache
		this.trips = true;
	}

	protected void onRoutesEntryProcessed(ThreadPoolExecutor executor) {
		// add to store and lookup cache
		feed.addRoutes(routeAdapter.getRoutes());

		this.routes = true;
		
	}

	protected void onAgencyEntryProcessed(ThreadPoolExecutor executor) {
		feed.add(agencyAdapter.getAgencies());
		
		this.agency = true;
	}

	protected abstract boolean onPostProcessing();
	
	public String getAgencyId() {
		return feed.getAgencyId();
	}

	protected void onCalendarEntryProcessed(ThreadPoolExecutor executor) {
		this.serviceCalendar = true;
	}

	protected void onCalendarDatesEntryProcessed(ThreadPoolExecutor executor) {
		this.serviceCalendarDates = true;
	}
	
	public GtfsFeed getHandlerCache() {
		return feed;
	}

	@Override
	public FileEntryStreamHandler getFileEntryStreamHandler(String name, long size, ThreadPoolExecutor executor) throws Exception {
		switch(name) {
			case "agency.txt" : return agencyAdapter.getFileEntryStreamHandler(this, executor, size);
			case "routes.txt": return routeAdapter.getFileEntryStreamHandler(this, executor, size);
			case "stops.txt": return stopAdapter.getFileEntryStreamHandler(this, executor, size);
			case "feed_info.txt": return feedInfoAdapter.getFileEntryStreamHandler(this, executor, size);
			case "transfers.txt": return transferAdapter.getFileEntryStreamHandler(this, executor, size);
		}
		return null;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy