progress dialog prototype
This commit is contained in:
@@ -10,6 +10,7 @@ public class MarketAnalyzer {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(MarketAnalyzer.class);
|
||||
|
||||
private final Market market;
|
||||
private MarketAnalyzerCallBack callback;
|
||||
private MarketFilter filter;
|
||||
private double tank;
|
||||
private double maxDistance;
|
||||
@@ -21,11 +22,20 @@ public class MarketAnalyzer {
|
||||
private final static Comparator<Order> orderComparator = (o1, o2) -> o2.compareTo(o1);
|
||||
|
||||
public MarketAnalyzer(Market market) {
|
||||
this(market, new MarketAnalyzerCallBack());
|
||||
}
|
||||
|
||||
public MarketAnalyzer(Market market, MarketAnalyzerCallBack callback) {
|
||||
this.market = market;
|
||||
this.callback = callback;
|
||||
this.limit = 100;
|
||||
this.segmentSize = 0;
|
||||
}
|
||||
|
||||
public void setCallback(MarketAnalyzerCallBack callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setFilter(MarketFilter filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
@@ -56,19 +66,23 @@ public class MarketAnalyzer {
|
||||
|
||||
public Collection<Order> getTop(double balance){
|
||||
LOG.debug("Get top {}", limit);
|
||||
Iterable<Place> places = getPlaces();
|
||||
Collection<Place> places = getPlaces();
|
||||
List<Order> top = new ArrayList<>(limit);
|
||||
callback.setCount(places.size());
|
||||
for (Place place : places) {
|
||||
LOG.trace("Check place {}", place);
|
||||
Collection<Order> orders = getOrders(place, balance, top.isEmpty() ? 0 : top.get(top.size()-1).getProfit());
|
||||
TopList.addAllToTop(top, orders, limit, orderComparator);
|
||||
if (callback.isCancel()) break;
|
||||
LOG.trace("Check place {}", place);
|
||||
Collection<Order> orders = getOrders(place, balance, top.isEmpty() ? 0 : top.get(top.size()-1).getProfit());
|
||||
TopList.addAllToTop(top, orders, limit, orderComparator);
|
||||
callback.inc();
|
||||
}
|
||||
callback.onEnd();
|
||||
return top;
|
||||
}
|
||||
|
||||
public Collection<Order> getOrders(Vendor vendor, double balance) {
|
||||
Collection<Place> places = getPlaces();
|
||||
Graph<Place> graph = new Graph<Place>(vendor.getPlace(), places, tank, maxDistance, true, jumps, Path::new);
|
||||
Graph<Place> graph = new Graph<Place>(vendor.getPlace(), places, tank, maxDistance, true, jumps, Path::new, callback.onStartGraph());
|
||||
return getOrders(graph, Collections.singleton(vendor), balance, 0);
|
||||
}
|
||||
|
||||
@@ -78,18 +92,22 @@ public class MarketAnalyzer {
|
||||
|
||||
private Collection<Order> getOrders(Place place, double balance, double lowProfit) {
|
||||
Collection<Place> places = getPlaces();
|
||||
Graph<Place> graph = new Graph<>(place, places, tank, maxDistance, true, jumps, Path::new);
|
||||
Graph<Place> graph = new Graph<>(place, places, tank, maxDistance, true, jumps, Path::new, callback.onStartGraph());
|
||||
return getOrders(graph, place.get(), balance, lowProfit);
|
||||
}
|
||||
|
||||
private Collection<Order> getOrders(Graph<Place> graph, Collection<Vendor> sellers, double balance, double lowProfit) {
|
||||
List<Order> res = new ArrayList<>(20);
|
||||
callback.setCount(sellers.size());
|
||||
for (Vendor vendor : sellers) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(vendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
for (Offer sell : vendor.getAllSellOffers()) {
|
||||
if (callback.isCancel()) break;
|
||||
LOG.trace("Sell offer {}", sell);
|
||||
if (sell.getCount() == 0) continue;
|
||||
long count = Order.getMaxCount(sell, balance, cargo);
|
||||
@@ -97,6 +115,7 @@ public class MarketAnalyzer {
|
||||
if (count == 0) continue;
|
||||
Iterator<Offer> buyers = market.getStatBuy(sell.getItem()).getOffers().descendingIterator();
|
||||
while (buyers.hasNext()){
|
||||
if (callback.isCancel()) break;
|
||||
Offer buy = buyers.next();
|
||||
if (isFiltered(buy.getVendor())){
|
||||
LOG.trace("Is filtered, skip");
|
||||
@@ -116,6 +135,7 @@ public class MarketAnalyzer {
|
||||
res.add(order);
|
||||
}
|
||||
}
|
||||
callback.inc();
|
||||
}
|
||||
res.sort(orderComparator);
|
||||
return res;
|
||||
@@ -123,17 +143,22 @@ public class MarketAnalyzer {
|
||||
|
||||
private Collection<Order> getOrders(Collection<Vendor> sellers, Collection<Vendor> buyers, double balance, double lowProfit) {
|
||||
List<Order> res = new ArrayList<>();
|
||||
callback.setCount(sellers.size());
|
||||
for (Vendor seller : sellers) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(seller)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
for (Offer sell : seller.getAllSellOffers()) {
|
||||
if (callback.isCancel()) break;
|
||||
if (sell.getCount() == 0) continue;
|
||||
long count = Order.getMaxCount(sell, balance, cargo);
|
||||
LOG.trace("Sell offer {}, count = {}", sell, count);
|
||||
if (count == 0) continue;
|
||||
for (Vendor buyer : buyers) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(buyer)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
continue;
|
||||
@@ -150,6 +175,7 @@ public class MarketAnalyzer {
|
||||
}
|
||||
}
|
||||
}
|
||||
callback.inc();
|
||||
}
|
||||
res.sort(orderComparator);
|
||||
return res;
|
||||
@@ -209,98 +235,131 @@ public class MarketAnalyzer {
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Vendor from, double balance){
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
callback.setCount(1);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
return searcher.getPaths(from, vendors, jumps, balance, cargo, limit);
|
||||
Collection<PathRoute> res = searcher.getPaths(from, vendors, jumps, balance, cargo, limit);
|
||||
callback.inc();
|
||||
callback.onEndSearch();
|
||||
return res;
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Place from, double balance){
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
callback.setCount(vendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor vendor : from.get()) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(vendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
Collection<PathRoute> paths = searcher.getPaths(vendor, vendors, jumps, balance, cargo, limit);
|
||||
if (paths.size()>0){
|
||||
return paths;
|
||||
}
|
||||
TopList.addAllToTop(top, paths, limit, RouteGraph.byProfitComparator);
|
||||
callback.inc();
|
||||
}
|
||||
return Collections.emptyList();
|
||||
callback.onEndSearch();
|
||||
return top;
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Vendor from, Vendor to, double balance){
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
return searcher.getPaths(from, to, getVendors(), jumps, balance, cargo, limit);
|
||||
callback.setCount(1);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
Collection<PathRoute> res = searcher.getPaths(from, to, getVendors(), jumps, balance, cargo, limit);
|
||||
callback.inc();
|
||||
callback.onEndSearch();
|
||||
return res;
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Place from, Place to, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> fVendors = from.get();
|
||||
Collection<Vendor> toVendors = to.get();
|
||||
int count = (int) Math.ceil(limit / fVendors.size());
|
||||
callback.setCount(fVendors.size() * toVendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor fromVendor : fVendors) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(fromVendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
for (Vendor toVendor : toVendors) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(toVendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
Collection<PathRoute> paths = searcher.getPaths(fromVendor, toVendor, vendors, jumps, balance, cargo, count);
|
||||
TopList.addAllToTop(top, paths, limit, RouteGraph.byProfitComparator);
|
||||
callback.inc();
|
||||
}
|
||||
}
|
||||
callback.onEndSearch();
|
||||
return top;
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Vendor from, Place to, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> toVendors = to.get();
|
||||
int count = (int) Math.ceil(limit / toVendors.size());
|
||||
callback.setCount(toVendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor toVendor : toVendors) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(toVendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
Collection<PathRoute> paths = searcher.getPaths(from, toVendor, vendors, jumps, balance, cargo, count);
|
||||
TopList.addAllToTop(top, paths, limit, RouteGraph.byProfitComparator);
|
||||
callback.inc();
|
||||
}
|
||||
callback.onEndSearch();
|
||||
return top;
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getPaths(Place from, Vendor to, double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
Collection<Vendor> fVendors = from.get();
|
||||
int count = (int) Math.ceil(limit / fVendors.size());
|
||||
callback.setCount(fVendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor fromVendor : fVendors) {
|
||||
if (callback.isCancel()) break;
|
||||
if (isFiltered(fromVendor)){
|
||||
LOG.trace("Is filtered, skip");
|
||||
callback.inc();
|
||||
continue;
|
||||
}
|
||||
Collection<PathRoute> paths = searcher.getPaths(fromVendor, to, vendors, jumps, balance, cargo, count);
|
||||
TopList.addAllToTop(top, paths, limit, RouteGraph.byProfitComparator);
|
||||
callback.inc();
|
||||
}
|
||||
callback.onEndSearch();
|
||||
return top;
|
||||
}
|
||||
|
||||
public Collection<PathRoute> getTopPaths(double balance){
|
||||
List<PathRoute> top = new ArrayList<>(limit);
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize);
|
||||
Collection<Vendor> vendors = getVendors();
|
||||
callback.setCount(vendors.size());
|
||||
RouteSearcher searcher = new RouteSearcher(maxDistance, tank, segmentSize, callback.onStartSearch());
|
||||
for (Vendor vendor : vendors) {
|
||||
if (callback.isCancel()) break;
|
||||
Collection<PathRoute> paths = searcher.getPaths(vendor, vendor, vendors, jumps, balance, cargo, 3);
|
||||
TopList.addAllToTop(top, paths, limit, RouteGraph.byProfitComparator);
|
||||
callback.inc();
|
||||
}
|
||||
callback.onEndSearch();
|
||||
return top;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package ru.trader.core;
|
||||
|
||||
import ru.trader.graph.GraphCallBack;
|
||||
import ru.trader.graph.RouteSearcherCallBack;
|
||||
|
||||
public class MarketAnalyzerCallBack {
|
||||
private volatile boolean cancel = false;
|
||||
private RouteSearcherCallBack callbackRoute;
|
||||
private GraphCallBack<Place> callbackGraph;
|
||||
|
||||
|
||||
protected RouteSearcherCallBack getRouteSearcherCallBackInstance(){
|
||||
return new RouteSearcherCallBack();
|
||||
}
|
||||
|
||||
protected GraphCallBack<Place> getGraphCallBackInstance(){
|
||||
return new GraphCallBack<>();
|
||||
}
|
||||
|
||||
public final GraphCallBack<Place> onStartGraph(){
|
||||
callbackGraph = getGraphCallBackInstance();
|
||||
return callbackGraph;
|
||||
}
|
||||
|
||||
public final void onEndGraph(){
|
||||
callbackGraph = null;
|
||||
}
|
||||
|
||||
public final RouteSearcherCallBack onStartSearch(){
|
||||
callbackRoute = getRouteSearcherCallBackInstance();
|
||||
return callbackRoute;
|
||||
}
|
||||
|
||||
public final void onEndSearch(){
|
||||
callbackRoute = null;
|
||||
onEnd();
|
||||
}
|
||||
|
||||
protected void onEnd(){}
|
||||
|
||||
public void setCount(long count){}
|
||||
public void inc(){}
|
||||
|
||||
|
||||
public final boolean isCancel() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public final void cancel(){
|
||||
if (cancel) return;
|
||||
this.cancel = true;
|
||||
if (callbackRoute != null){
|
||||
callbackRoute.cancel();
|
||||
callbackRoute = null;
|
||||
}
|
||||
if (callbackGraph != null){
|
||||
callbackGraph.cancel();
|
||||
callbackGraph = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,6 +23,7 @@ public class Graph<T extends Connectable<T>> {
|
||||
|
||||
protected final Vertex<T> root;
|
||||
protected final Map<T,Vertex<T>> vertexes;
|
||||
private final GraphCallBack<T> callback;
|
||||
|
||||
protected final double stock;
|
||||
protected final double maxDistance;
|
||||
@@ -48,15 +49,22 @@ public class Graph<T extends Connectable<T>> {
|
||||
}
|
||||
|
||||
public Graph(T start, Collection<T> set, double stock, double maxDistance, boolean withRefill, int maxDeep, PathConstructor<T> pathFabric) {
|
||||
this(start, set, stock, maxDistance, withRefill, maxDeep, pathFabric, new GraphCallBack<>());
|
||||
}
|
||||
|
||||
public Graph(T start, Collection<T> set, double stock, double maxDistance, boolean withRefill, int maxDeep, PathConstructor<T> pathFabric, GraphCallBack<T> callback) {
|
||||
this.maxDistance = maxDistance;
|
||||
this.stock = stock;
|
||||
this.withRefill = withRefill;
|
||||
this.pathFabric = pathFabric;
|
||||
this.callback = callback;
|
||||
root = new Vertex<>(start);
|
||||
root.setLevel(maxDeep);
|
||||
vertexes = new ConcurrentHashMap<>(50, 0.9f, THRESHOLD);
|
||||
vertexes.put(root.getEntry(), root);
|
||||
callback.onStartBuild(start);
|
||||
build(root, set, maxDeep, stock);
|
||||
callback.onEndBuild();
|
||||
}
|
||||
|
||||
private void build(Vertex<T> root, Collection<T> set, int maxDeep, double stock) {
|
||||
@@ -81,7 +89,9 @@ public class Graph<T extends Connectable<T>> {
|
||||
}
|
||||
|
||||
private void findPathsTo(Vertex<T> target, TopList<Path<T>> res, int deep){
|
||||
callback.onStartFind(root, target);
|
||||
POOL.invoke(new PathFinder(res, pathFabric.build(root), target, deep-1, stock));
|
||||
callback.onEndFind();
|
||||
}
|
||||
|
||||
public List<Path<T>> getPathsTo(T entry){
|
||||
@@ -95,7 +105,9 @@ public class Graph<T extends Connectable<T>> {
|
||||
public TopList<Path<T>> getPathsTo(T entry, int max, int deep){
|
||||
Vertex<T> target = getVertex(entry);
|
||||
TopList<Path<T>> paths = newTopList(max);
|
||||
callback.setCount(1);
|
||||
findPathsTo(target, paths, deep);
|
||||
callback.inc();
|
||||
paths.finish();
|
||||
return paths;
|
||||
}
|
||||
@@ -106,12 +118,15 @@ public class Graph<T extends Connectable<T>> {
|
||||
|
||||
public TopList<Path<T>> getPaths(int count, int deep){
|
||||
TopList<Path<T>> paths = newTopList(count);
|
||||
callback.setCount(vertexes.size());
|
||||
for (Vertex<T> target : vertexes.values()) {
|
||||
if (callback.isCancel()) break;
|
||||
TopList<Path<T>> p = newTopList(minJumps);
|
||||
findPathsTo(target, p, deep);
|
||||
for (Path<T> path : p.getList()) {
|
||||
paths.add(path);
|
||||
}
|
||||
callback.inc();
|
||||
}
|
||||
paths.finish();
|
||||
return paths;
|
||||
@@ -204,6 +219,7 @@ public class Graph<T extends Connectable<T>> {
|
||||
ArrayList<GraphBuilder> subTasks = new ArrayList<>(set.size());
|
||||
Iterator<T> iterator = set.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (callback.isCancel()) break;
|
||||
T entry = iterator.next();
|
||||
if (entry == vertex.getEntry()) continue;
|
||||
double distance = vertex.getEntry().getDistance(entry);
|
||||
@@ -236,14 +252,22 @@ public class Graph<T extends Connectable<T>> {
|
||||
}
|
||||
if (subTasks.size() == THRESHOLD || !iterator.hasNext()){
|
||||
for (GraphBuilder subTask : subTasks) {
|
||||
subTask.join();
|
||||
if (callback.isCancel()){
|
||||
subTask.cancel(true);
|
||||
} else {
|
||||
subTask.join();
|
||||
}
|
||||
}
|
||||
subTasks.clear();
|
||||
}
|
||||
}
|
||||
if (!subTasks.isEmpty()){
|
||||
for (GraphBuilder subTask : subTasks) {
|
||||
subTask.join();
|
||||
if (callback.isCancel()){
|
||||
subTask.cancel(true);
|
||||
} else {
|
||||
subTask.join();
|
||||
}
|
||||
}
|
||||
subTasks.clear();
|
||||
}
|
||||
@@ -282,6 +306,7 @@ public class Graph<T extends Connectable<T>> {
|
||||
synchronized (paths){
|
||||
if (!paths.add(path)) complete(null);
|
||||
}
|
||||
callback.onFound();
|
||||
}
|
||||
}
|
||||
if (deep > 0 ){
|
||||
@@ -291,7 +316,7 @@ public class Graph<T extends Connectable<T>> {
|
||||
Iterator<Edge<T>> iterator = source.getEdges().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Edge<T> next = iterator.next();
|
||||
if (isDone()) break;
|
||||
if (isDone() || callback.isCancel()) break;
|
||||
// target already added if source consist edge
|
||||
if (next.isConnect(target)) continue;
|
||||
if (!distanceFilter.test(next.getLength())) continue;
|
||||
@@ -305,8 +330,8 @@ public class Graph<T extends Connectable<T>> {
|
||||
subTasks.add(task);
|
||||
if (subTasks.size() == THRESHOLD || !iterator.hasNext()){
|
||||
for (PathFinder subTask : subTasks) {
|
||||
if (isDone()) {
|
||||
subTask.cancel(false);
|
||||
if (isDone() || callback.isCancel()) {
|
||||
subTask.cancel(callback.isCancel());
|
||||
} else {
|
||||
subTask.join();
|
||||
}
|
||||
@@ -316,8 +341,8 @@ public class Graph<T extends Connectable<T>> {
|
||||
}
|
||||
if (!subTasks.isEmpty()){
|
||||
for (PathFinder subTask : subTasks) {
|
||||
if (isDone()) {
|
||||
subTask.cancel(false);
|
||||
if (isDone() || callback.isCancel()) {
|
||||
subTask.cancel(callback.isCancel());
|
||||
} else {
|
||||
subTask.join();
|
||||
}
|
||||
|
||||
27
core/src/main/java/ru/trader/graph/GraphCallBack.java
Normal file
27
core/src/main/java/ru/trader/graph/GraphCallBack.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package ru.trader.graph;
|
||||
|
||||
public class GraphCallBack<T extends Connectable<T>> {
|
||||
|
||||
private volatile boolean cancel = false;
|
||||
|
||||
public void onStartBuild(T from){}
|
||||
public void onEndBuild(){}
|
||||
|
||||
|
||||
public void onStartFind(Vertex<T> from, Vertex<T> to){}
|
||||
public void onFound(){}
|
||||
public void onEndFind(){}
|
||||
|
||||
|
||||
public void setCount(long count){}
|
||||
public void inc(){}
|
||||
|
||||
public final boolean isCancel() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public final void cancel(){
|
||||
this.cancel = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,9 +31,12 @@ public class RouteGraph extends Graph<Vendor> {
|
||||
public RouteGraph(Vendor start, Collection<Vendor> set, double stock, double maxDistance, boolean withRefill, int maxDeep) {
|
||||
this(start, set, stock, maxDistance, withRefill, maxDeep, false);
|
||||
}
|
||||
|
||||
public RouteGraph(Vendor start, Collection<Vendor> set, double stock, double maxDistance, boolean withRefill, int maxDeep, boolean groupRes) {
|
||||
super(start, set, stock, maxDistance, withRefill, maxDeep, groupRes ? PathRoute::buildAvg : PathRoute::new);
|
||||
this(start, set, stock, maxDistance, withRefill, maxDeep, groupRes, new GraphCallBack<>());
|
||||
}
|
||||
|
||||
public RouteGraph(Vendor start, Collection<Vendor> set, double stock, double maxDistance, boolean withRefill, int maxDeep, boolean groupRes, GraphCallBack<Vendor> callback) {
|
||||
super(start, set, stock, maxDistance, withRefill, maxDeep, groupRes ? PathRoute::buildAvg : PathRoute::new, callback);
|
||||
if (groupRes){
|
||||
this.groupRes = maxDeep > minJumps;
|
||||
}
|
||||
|
||||
@@ -14,17 +14,19 @@ public class RouteSearcher {
|
||||
private final static ForkJoinPool POOL = new ForkJoinPool();
|
||||
private final static int THRESHOLD = (int) Math.ceil(Runtime.getRuntime().availableProcessors()/2.0);
|
||||
|
||||
private final RouteSearcherCallBack callback;
|
||||
private final double maxDistance;
|
||||
private final double stock;
|
||||
private final int segmentSize;
|
||||
|
||||
public RouteSearcher(double maxDistance, double stock) {
|
||||
this(maxDistance, stock, 0);
|
||||
this(maxDistance, stock, 0, new RouteSearcherCallBack());
|
||||
}
|
||||
public RouteSearcher(double maxDistance, double stock, int segmentSize) {
|
||||
public RouteSearcher(double maxDistance, double stock, int segmentSize, RouteSearcherCallBack callback) {
|
||||
this.maxDistance = maxDistance;
|
||||
this.stock = stock;
|
||||
this.segmentSize = segmentSize;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public List<PathRoute> getPaths(Vendor from, Vendor to, Collection<Vendor> vendors, int jumps, double balance, int cargo, int limit){
|
||||
@@ -56,8 +58,10 @@ public class RouteSearcher {
|
||||
|
||||
@Override
|
||||
protected List<PathRoute> compute() {
|
||||
if (callback.isCancel()) return Collections.emptyList();
|
||||
LOG.trace("Start search route to {} from {}, jumps {}", source, target, jumps);
|
||||
RouteGraph sGraph = new RouteGraph(source, vendors, stock, maxDistance, true, jumps, true);
|
||||
GraphCallBack<Vendor> gCallBack = callback.onStart();
|
||||
RouteGraph sGraph = new RouteGraph(source, vendors, stock, maxDistance, true, jumps, true, gCallBack);
|
||||
int jumpsToAll = sGraph.getMinJumps();
|
||||
LOG.trace("Segment jumps {}", jumpsToAll);
|
||||
sGraph.setCargo(cargo);
|
||||
@@ -87,8 +91,10 @@ public class RouteSearcher {
|
||||
res.add(path);
|
||||
}
|
||||
}
|
||||
if (callback.isCancel()) break;
|
||||
subTasks.clear();
|
||||
for (int taskIndex = 0; taskIndex < THRESHOLD && i+taskIndex < paths.size(); taskIndex++) {
|
||||
if (callback.isCancel()) break;
|
||||
PathRoute path = (PathRoute) paths.get(i+taskIndex);
|
||||
double newBalance = balance + path.getRoot().getProfit();
|
||||
SegmentSearcher task = new SegmentSearcher(path.get(), target, vendors, jumps - path.getLength(), newBalance, cargo, 1);
|
||||
@@ -103,6 +109,7 @@ public class RouteSearcher {
|
||||
}
|
||||
}
|
||||
res.finish();
|
||||
callback.onEnd(gCallBack);
|
||||
return res.getList();
|
||||
}
|
||||
|
||||
@@ -116,6 +123,10 @@ public class RouteSearcher {
|
||||
|
||||
|
||||
private void add(SegmentSearcher task, PathRoute path, TopList<PathRoute> res){
|
||||
if (callback.isCancel()){
|
||||
task.cancel(true);
|
||||
return;
|
||||
}
|
||||
List<PathRoute> tail = task.join();
|
||||
if (tail.isEmpty()){
|
||||
LOG.trace("Not found route from {} to {}, jumps {}", task.source, task.target, task.jumps);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package ru.trader.graph;
|
||||
|
||||
import ru.trader.core.Vendor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class RouteSearcherCallBack {
|
||||
|
||||
private volatile boolean cancel = false;
|
||||
private final List<GraphCallBack<Vendor>> callbacks = new LinkedList<>();
|
||||
|
||||
public final GraphCallBack<Vendor> onStart(){
|
||||
GraphCallBack<Vendor> callback = getGraphCallBackInstance();
|
||||
if (cancel) return callback;
|
||||
synchronized (callbacks) {
|
||||
callbacks.add(callback);
|
||||
}
|
||||
return callback;
|
||||
}
|
||||
|
||||
public final void onEnd( GraphCallBack<Vendor> callback){
|
||||
synchronized (callbacks) {
|
||||
callbacks.remove(callback);
|
||||
}
|
||||
}
|
||||
|
||||
protected GraphCallBack<Vendor> getGraphCallBackInstance(){
|
||||
return new GraphCallBack<>();
|
||||
}
|
||||
|
||||
public final boolean isCancel() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public final void cancel(){
|
||||
if (cancel) return;
|
||||
this.cancel = true;
|
||||
synchronized (callbacks){
|
||||
callbacks.forEach(GraphCallBack::cancel);
|
||||
callbacks.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user