All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.skjolber.dc.gtfs.mt.TripAdapter Maven / Gradle / Ivy
package com.github.skjolber.dc.gtfs.mt;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import com.github.skjolber.dc.GtfsFeed;
import com.github.skjolber.dc.gtfs.GtfsIntermediateProcessor;
import com.github.skjolber.dc.model.FeedId;
import com.github.skjolber.dc.model.Route;
import com.github.skjolber.dc.model.Service;
import com.github.skjolber.dc.model.Trip;
import com.github.skjolber.stcsv.CsvReader;
import com.github.skjolber.stcsv.databinder.CsvMapper2;
import com.github.skjolber.stcsv.databinder.StaticCsvMapper;
import com.github.skjolber.unzip.FileChunkSplitter;
import com.github.skjolber.unzip.FileEntryChunkStreamHandler;
import com.github.skjolber.unzip.FileEntryHandler;
import com.github.skjolber.unzip.FileEntryStreamHandler;
import com.github.skjolber.unzip.NewlineChunkSplitter;
import com.github.skjolber.unzip.csv.AbstractSesselTjonnaCsvFileEntryChunkStreamHandler;
import com.github.skjolber.unzip.csv.AbstractSesselTjonnaCsvFileEntryStreamHandler;
import com.github.skjolber.unzip.csv.CsvLineHandler;
import com.github.skjolber.unzip.csv.CsvLineHandlerFactory;
/**
*
* For chunked / multi-threaded parsing.
*
*/
@SuppressWarnings("unchecked")
public class TripAdapter implements CsvLineHandlerFactory {
protected static CsvMapper2> parser;
static {
parser = CsvMapper2.builder(Trip.class, (Class>)(Class>)GtfsIntermediateProcessor.class)
.stringField("route_id")
.consumer( (t, i, id) -> i.add(0, id, t))
.quoted()
.optional()
.stringField("service_id")
.consumer( (t, i, id) -> i.add(1, id, t) )
.required()
.stringField("trip_id")
.consumer( (t, id) -> t.setId(id) )
.required()
.stringField("trip_headsign")
.setter(Trip::setHeadsign)
.quoted()
.optional()
.stringField("direction_id")
.setter(Trip::setDirectionId)
.optional()
.stringField("shape_id")
.consumer( (t, i, id) -> t.setShapeId(new FeedId(i.getFeed().getAgencyId(), id) ) )
.optional()
.integerField("wheelchair_accessible")
.setter(Trip::setWheelchairAccessible)
.optional()
.build();
}
protected Map handlers = new ConcurrentHashMap<>(Runtime.getRuntime().availableProcessors() * 2);
protected Map> processors = new ConcurrentHashMap<>(Runtime.getRuntime().availableProcessors());
protected int chunkLength;
protected GtfsFeed feed;
public TripAdapter(int chunkLength, GtfsFeed feed) {
this.chunkLength = chunkLength;
this.feed = feed;
}
@Override
public CsvLineHandler getHandler(String fileName, ThreadPoolExecutor executor) {
if(!fileName.equals("trips.txt")) {
throw new IllegalArgumentException();
}
TripHandler csvLineHandler = (TripHandler) handlers.get(Thread.currentThread());
if(csvLineHandler == null) {
csvLineHandler = new TripHandler();
handlers.put(Thread.currentThread(), csvLineHandler);
}
return (CsvLineHandler) csvLineHandler;
}
private class TripCsvFileEntryStreamHandler extends AbstractSesselTjonnaCsvFileEntryStreamHandler {
public TripCsvFileEntryStreamHandler(String name, CsvLineHandlerFactory csvLineHandlerFactory, long size, FileEntryHandler fileEntryHandler, ThreadPoolExecutor executor) {
super(name, csvLineHandlerFactory, fileEntryHandler, executor);
}
public TripCsvFileEntryStreamHandler(String name, CsvLineHandlerFactory csvLineHandlerFactory, FileEntryHandler fileEntryHandler, ThreadPoolExecutor executor) {
super(name, csvLineHandlerFactory, fileEntryHandler, executor);
}
@Override
protected CsvReader createCsvReader(Reader reader, ThreadPoolExecutor executorService) throws Exception {
return parser.create(reader, newIntermediateProcessor());
}
}
private class TripCsvFileEntryChunkStreamHandler extends AbstractSesselTjonnaCsvFileEntryChunkStreamHandler {
public TripCsvFileEntryChunkStreamHandler(String name, Charset charset, FileChunkSplitter fileChunkSplitter, CsvLineHandlerFactory csvLineHandlerFactory) {
super(name, charset, fileChunkSplitter, csvLineHandlerFactory);
}
@Override
protected StaticCsvMapper createStaticCsvMapper(String firstLine) throws Exception {
return new StaticCsvMapperAdapter>(parser.buildStaticCsvMapper(firstLine)) {
@Override
protected GtfsIntermediateProcessor newIntermediateProcessor() {
return TripAdapter.this.newIntermediateProcessor();
}
};
}
}
protected GtfsIntermediateProcessor newIntermediateProcessor() {
GtfsIntermediateProcessor processor = processors.get(Thread.currentThread());
if(processor == null) {
processor = new GtfsIntermediateProcessor(2, feed);
processors.put(Thread.currentThread(), processor);
}
return processor;
}
public FileEntryStreamHandler getFileEntryStreamHandler(FileEntryHandler fileEntryHandler, ThreadPoolExecutor executor, long size) throws Exception {
/*
if(executor.getCorePoolSize() >= 4) {
// prevent deadlocks by carefully choosing the parallel buffer size
return new TripCsvFileEntryStreamHandler("trips.txt", this, Math.min(chunkLength, size), fileEntryHandler, executor);
}
*/
return new TripCsvFileEntryStreamHandler("trips.txt", this, fileEntryHandler, executor);
}
public FileEntryChunkStreamHandler getFileEntryChunkedStreamHandler() throws Exception {
return new TripCsvFileEntryChunkStreamHandler("trips.txt", StandardCharsets.UTF_8, new NewlineChunkSplitter(chunkLength), this);
}
public void resolveRoutes() {
for (GtfsIntermediateProcessor p : processors.values()) {
Map> tripByRouteId = p.getById(0);
for (Entry> entry : tripByRouteId.entrySet()) {
Route route = feed.getRoute(entry.getKey());
for(Trip trip : entry.getValue()) {
trip.setRoute(route);
}
}
}
}
public void resolveServices() {
for (GtfsIntermediateProcessor p : processors.values()) {
Map> tripByServiceId = p.getById(1);
for (Entry> entry : tripByServiceId.entrySet()) {
Service s = feed.getService(entry.getKey());
if(s == null) {
throw new RuntimeException("Unknown service " + entry.getKey());
}
for(Trip trip : entry.getValue()) {
trip.setService(s);
s.add(trip);
}
}
}
}
public List resolveTrips() {
List trips = new ArrayList<>(4096);
for (TripHandler tripHandler : handlers.values()) {
trips.addAll(tripHandler.getTrips());
}
return trips;
}
}