From eb9f42ddb6c371a463f3bea42ea3220caf7f4fd5 Mon Sep 17 00:00:00 2001 From: iMoHax Date: Fri, 31 Jul 2015 10:58:01 +0300 Subject: [PATCH] add callbacks to crawler --- .../java/ru/trader/model/MarketModel.java | 5 + .../java/ru/trader/services/AnalyzerTask.java | 100 +++--------------- .../ru/trader/analysis/RouteSearcher.java | 17 +-- .../java/ru/trader/analysis/VendorsGraph.java | 27 +++-- .../trader/analysis/graph/AbstractGraph.java | 4 - .../ru/trader/analysis/graph/CCrawler.java | 18 ++-- .../analysis/graph/ConnectibleGraph.java | 5 - .../ru/trader/analysis/graph/Crawler.java | 50 +++++---- .../analysis/graph/CrawlerCallBack.java | 30 ++++++ .../java/ru/trader/core/MarketAnalyzer.java | 38 +++---- .../trader/core/MarketAnalyzerCallBack.java | 62 +++-------- .../java/ru/trader/graph/GraphCallBack.java | 29 ----- .../trader/graph/RouteSearcherCallBack.java | 44 -------- .../ru/trader/analysis/VendorsGraphTest.java | 12 +-- .../ru/trader/analysis/graph/CrawlerTest.java | 21 ++-- .../ru/trader/analysis/graph/GraphTest.java | 9 +- .../analysis/graph/SimpleCollector.java | 4 +- core/src/test/resources/log4j.properties | 2 +- 18 files changed, 180 insertions(+), 297 deletions(-) create mode 100644 core/src/main/java/ru/trader/analysis/graph/CrawlerCallBack.java delete mode 100644 core/src/main/java/ru/trader/graph/GraphCallBack.java delete mode 100644 core/src/main/java/ru/trader/graph/RouteSearcherCallBack.java diff --git a/client/src/main/java/ru/trader/model/MarketModel.java b/client/src/main/java/ru/trader/model/MarketModel.java index 81ca03a..3a5fbc9 100644 --- a/client/src/main/java/ru/trader/model/MarketModel.java +++ b/client/src/main/java/ru/trader/model/MarketModel.java @@ -10,6 +10,7 @@ import javafx.collections.ObservableList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.trader.World; +import ru.trader.analysis.AnalysisCallBack; import ru.trader.analysis.Route; import ru.trader.controllers.ProgressController; import ru.trader.controllers.Screeners; @@ -67,6 +68,10 @@ public class MarketModel { return analyzer; } + public MarketAnalyzer getAnalyzer(AnalysisCallBack callback) { + return analyzer.changeCallBack(callback); + } + public ModelFabric getModeler() { return modeler; } diff --git a/client/src/main/java/ru/trader/services/AnalyzerTask.java b/client/src/main/java/ru/trader/services/AnalyzerTask.java index 6866bca..7dd790f 100644 --- a/client/src/main/java/ru/trader/services/AnalyzerTask.java +++ b/client/src/main/java/ru/trader/services/AnalyzerTask.java @@ -4,14 +4,8 @@ import javafx.application.Platform; import javafx.beans.property.LongProperty; import javafx.beans.property.SimpleLongProperty; import javafx.concurrent.Task; -import ru.trader.analysis.graph.Vertex; +import ru.trader.analysis.AnalysisCallBack; import ru.trader.core.MarketAnalyzer; -import ru.trader.core.MarketAnalyzerCallBack; -import ru.trader.core.Place; -import ru.trader.core.Vendor; -import ru.trader.graph.Connectable; -import ru.trader.graph.GraphCallBack; -import ru.trader.graph.RouteSearcherCallBack; import ru.trader.model.MarketModel; import ru.trader.view.support.Localization; @@ -19,8 +13,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; public abstract class AnalyzerTask extends Task { - private final AnalyzerCallBack callback; - protected final MarketAnalyzer analyzer; + private final AnalyzerCallBack callback; protected final MarketAnalyzer analyzer; private final LongProperty found; private final AtomicReference foundUpdate; @@ -28,9 +21,8 @@ public abstract class AnalyzerTask extends Task { public AnalyzerTask(MarketModel market) { foundUpdate = new AtomicReference<>((long) 0); found = new SimpleLongProperty(0); - analyzer = market.getAnalyzer(); callback = new AnalyzerCallBack(); - analyzer.setCallback(callback); + analyzer = market.getAnalyzer(callback); } public long getFound() { @@ -59,7 +51,7 @@ public abstract class AnalyzerTask extends Task { callback.cancel(); } - private class AnalyzerCallBack extends MarketAnalyzerCallBack { + private class AnalyzerCallBack extends AnalysisCallBack { private final AtomicLong max; private final AtomicLong counter; private final AtomicLong found; @@ -70,21 +62,20 @@ public abstract class AnalyzerTask extends Task { found = new AtomicLong(0); } - @Override - protected RouteSearcherCallBack getRouteSearcherCallBackInstance() { - return new RSCallBack(); - } - @Override - protected GraphCallBack getGraphCallBackInstance() { - return new GCallBack(); + public void startStage(String id) { + super.startStage(id); } @Override - protected void onEnd() { - updateProgress(counter.incrementAndGet(), max.get()); - updateMessage(Localization.getString("analyser.finish")); + public String getMessage(String key) { + return Localization.getString(key); + } + + @Override + public void print(String message) { + super.print(message); } @Override @@ -95,69 +86,12 @@ public abstract class AnalyzerTask extends Task { @Override public void inc() { updateProgress(counter.incrementAndGet(), max.get()); + updateFound(found.incrementAndGet()); } - private class RSCallBack extends RouteSearcherCallBack { - @Override - protected GraphCallBack getGraphCallBackInstance() { - return new GCallBack(){ - @Override - public void onStartBuild(Vendor from) { - updateMessage(String.format(Localization.getString("analyzer.graph.station.build"), from.getPlace().getName(), from.getName())); - } - - @Override - public void onStartFind(Vertex from, Vertex to) { - if (to != null) { - updateMessage(String.format(Localization.getString("analyzer.find.route"), - from.getEntry().getPlace().getName(), - from.getEntry().getName(), - to.getEntry().getPlace().getName(), - to.getEntry().getName() - )); - } else { - updateMessage(String.format(Localization.getString("analyzer.find.routes"), - from.getEntry().getPlace().getName(), - from.getEntry().getName() - )); - } - } - }; - } - } - - private class GCallBack> extends GraphCallBack { - - @Override - public void onStartBuild(T from) { - updateMessage(String.format(Localization.getString("analyzer.graph.build"), from)); - } - - @Override - public void onEndBuild() { - updateProgress(counter.incrementAndGet(), max.get()); - updateMessage(Localization.getString("analyzer.graph.success")); - } - - @Override - public void onFound() { - updateFound(found.incrementAndGet()); - } - - @Override - public void onEndFind() { - updateMessage(String.format(Localization.getString("analyzer.find.success"), found.get())); - } - - @Override - public void setMax(long value) { - max.addAndGet(value); - } - - @Override - public void inc() { - updateProgress(counter.incrementAndGet(), max.get()); - } + @Override + public void endStage(String id) { + updateProgress(counter.incrementAndGet(), max.get()); } } } diff --git a/core/src/main/java/ru/trader/analysis/RouteSearcher.java b/core/src/main/java/ru/trader/analysis/RouteSearcher.java index be648a2..9ae9afd 100644 --- a/core/src/main/java/ru/trader/analysis/RouteSearcher.java +++ b/core/src/main/java/ru/trader/analysis/RouteSearcher.java @@ -13,9 +13,15 @@ import java.util.*; public class RouteSearcher { private final static Logger LOG = LoggerFactory.getLogger(RouteSearcher.class); private final Scorer scorer; + private final AnalysisCallBack callback; public RouteSearcher(Scorer scorer) { + this(scorer, new AnalysisCallBack()); + } + + public RouteSearcher(Scorer scorer, AnalysisCallBack callback) { this.scorer = scorer; + this.callback = callback; } public List> getPath(Place from, Place to, Collection places){ @@ -34,12 +40,12 @@ public class RouteSearcher { private List>> search(Place source, Place target, Collection places, int count, RouteSpecification specification){ Profile profile = scorer.getProfile(); LOG.trace("Start search path from {} to {} ", source, target); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, callback); LOG.trace("Build connectible graph"); graph.build(source, places); LOG.trace("Graph is builds"); List>> paths = new ArrayList<>(); - Crawler crawler = specification != null ? new CCrawler<>(graph, specification, paths::add) : new CCrawler<>(graph, paths::add); + Crawler crawler = specification != null ? new CCrawler<>(graph, specification, paths::add, callback) : new CCrawler<>(graph, paths::add, callback); crawler.setMaxSize(profile.getJumps()); if (profile.getPathPriority() == Profile.PATH_PRIORITY.FAST){ crawler.findFast(target, count); @@ -78,12 +84,12 @@ public class RouteSearcher { private List search(Vendor source, Vendor target, Collection vendors, int count, RouteSpecification specification){ LOG.trace("Start search route from {} to {}", source, target); - VendorsGraph vGraph = new VendorsGraph(scorer); + VendorsGraph vGraph = new VendorsGraph(scorer, callback); LOG.trace("Build vendors graph"); vGraph.build(source, vendors); LOG.trace("Graph is builds"); RouteCollector collector = new RouteCollector(); - Crawler crawler = specification != null ? vGraph.crawler(specification, collector::add) : vGraph.crawler(collector::add); + Crawler crawler = specification != null ? vGraph.crawler(specification, collector::add, callback) : vGraph.crawler(collector::add, callback); crawler.setMaxSize(scorer.getProfile().getLands()); crawler.findMin(target, count); return collector.get(); @@ -96,11 +102,10 @@ public class RouteSearcher { private class RouteCollector { private List routes = new ArrayList<>(); - public boolean add(List> edges){ + public void add(List> edges){ Route route = toRoute(edges); route.setBalance(scorer.getProfile().getBalance()); routes.add(route); - return true; } public List get() { diff --git a/core/src/main/java/ru/trader/analysis/VendorsGraph.java b/core/src/main/java/ru/trader/analysis/VendorsGraph.java index 65a5460..09db604 100644 --- a/core/src/main/java/ru/trader/analysis/VendorsGraph.java +++ b/core/src/main/java/ru/trader/analysis/VendorsGraph.java @@ -7,7 +7,7 @@ import ru.trader.analysis.graph.*; import ru.trader.core.*; import java.util.*; -import java.util.function.Predicate; +import java.util.function.Consumer; import java.util.stream.Collectors; @@ -17,22 +17,17 @@ public class VendorsGraph extends ConnectibleGraph { private final Scorer scorer; private final List deferredTasks = new ArrayList<>(); - public VendorsGraph(Scorer scorer) { - super(scorer.getProfile()); - this.scorer = scorer; - } - public VendorsGraph(Scorer scorer, AnalysisCallBack callback) { super(scorer.getProfile(), callback); this.scorer = scorer; } - public VendorsCrawler crawler(Predicate>> onFoundFunc){ - return new VendorsCrawler(onFoundFunc); + public VendorsCrawler crawler(Consumer>> onFoundFunc, AnalysisCallBack callback){ + return new VendorsCrawler(onFoundFunc, callback); } - public VendorsCrawler crawler(RouteSpecification specification, Predicate>> onFoundFunc){ - return new VendorsCrawler(specification, onFoundFunc); + public VendorsCrawler crawler(RouteSpecification specification, Consumer>> onFoundFunc, AnalysisCallBack callback){ + return new VendorsCrawler(specification, onFoundFunc, callback); } @Override @@ -61,6 +56,7 @@ public class VendorsGraph extends ConnectibleGraph { private void runDeferredTasks(){ deferredTasks.sort((b1,b2) -> Integer.compare(b2.getDeep(), b1.getDeep())); for (VendorsGraphBuilder task : deferredTasks) { + if (callback.isCancel()) break; task.compute(); } deferredTasks.clear(); @@ -154,6 +150,7 @@ public class VendorsGraph extends ConnectibleGraph { VendorsGraphBuilder h = this; Path path = new Path<>(Collections.singleton(lastEdge)); while (h != null){ + if (callback.isCancel()) break; BuildEdge cEdge = h.edge; Vertex source = cEdge.getSource(); if (source.equals(vertex)){ @@ -204,8 +201,10 @@ public class VendorsGraph extends ConnectibleGraph { int i = 1; Path path = paths != null ? paths.get(0) : new Path<>(Collections.singleton((BuildEdge)lastEdge)); while (path != null){ + if (callback.isCancel()) break; VendorsGraphBuilder h = this; while (h != null){ + if (callback.isCancel()) break; if (h.limit >= path.getMinFuel() && h.limit <= path.getMaxFuel()){ BuildEdge cEdge = h.edge; Vertex source = cEdge.getSource(); @@ -464,14 +463,14 @@ public class VendorsGraph extends ConnectibleGraph { private double startFuel; private double startBalance; - protected VendorsCrawler(Predicate>> onFoundFunc) { - super(VendorsGraph.this, onFoundFunc); + protected VendorsCrawler(Consumer>> onFoundFunc, AnalysisCallBack callback) { + super(VendorsGraph.this, onFoundFunc, callback); startFuel = getShip().getTank(); startBalance = getProfile().getBalance(); } - protected VendorsCrawler(RouteSpecification specification, Predicate>> onFoundFunc) { - super(VendorsGraph.this, specification, onFoundFunc); + protected VendorsCrawler(RouteSpecification specification, Consumer>> onFoundFunc, AnalysisCallBack callback) { + super(VendorsGraph.this, specification, onFoundFunc, callback); startFuel = getShip().getTank(); startBalance = getProfile().getBalance(); } diff --git a/core/src/main/java/ru/trader/analysis/graph/AbstractGraph.java b/core/src/main/java/ru/trader/analysis/graph/AbstractGraph.java index 3424327..a4ad73f 100644 --- a/core/src/main/java/ru/trader/analysis/graph/AbstractGraph.java +++ b/core/src/main/java/ru/trader/analysis/graph/AbstractGraph.java @@ -17,10 +17,6 @@ public abstract class AbstractGraph implements Graph { protected int minJumps; private final ReentrantLock lock = new ReentrantLock(); - protected AbstractGraph() { - this(new AnalysisCallBack()); - } - protected AbstractGraph(AnalysisCallBack callback) { this.callback = new GraphCallBack(callback); vertexes = new ArrayList<>(); diff --git a/core/src/main/java/ru/trader/analysis/graph/CCrawler.java b/core/src/main/java/ru/trader/analysis/graph/CCrawler.java index 3bb2b44..d428f6c 100644 --- a/core/src/main/java/ru/trader/analysis/graph/CCrawler.java +++ b/core/src/main/java/ru/trader/analysis/graph/CCrawler.java @@ -2,6 +2,7 @@ package ru.trader.analysis.graph; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ru.trader.analysis.AnalysisCallBack; import ru.trader.analysis.RouteSpecification; import ru.trader.core.Profile; import ru.trader.core.Ship; @@ -9,23 +10,26 @@ import ru.trader.graph.Connectable; import java.util.Collection; import java.util.List; -import java.util.function.Predicate; +import java.util.function.Consumer; import java.util.stream.Collectors; public class CCrawler> extends Crawler { private final static Logger LOG = LoggerFactory.getLogger(CCrawler.class); private double startFuel; - public CCrawler(ConnectibleGraph graph, Predicate>> onFoundFunc) { - super(graph, onFoundFunc); - startFuel = getShip().getTank(); + public CCrawler(ConnectibleGraph graph, Consumer>> onFoundFunc, AnalysisCallBack callback) { + super(graph, onFoundFunc, callback); + init(); } - public CCrawler(ConnectibleGraph graph, RouteSpecification specification, Predicate>> onFoundFunc) { - super(graph, specification, onFoundFunc); - startFuel = getShip().getTank(); + public CCrawler(ConnectibleGraph graph, RouteSpecification specification, Consumer>> onFoundFunc, AnalysisCallBack callback) { + super(graph, specification, onFoundFunc, callback); + init(); } + private void init(){ + startFuel = getShip().getTank(); + } protected Ship getShip(){ return ((ConnectibleGraph)graph).getShip(); diff --git a/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java b/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java index fab24bf..002c68a 100644 --- a/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java +++ b/core/src/main/java/ru/trader/analysis/graph/ConnectibleGraph.java @@ -14,11 +14,6 @@ public class ConnectibleGraph> extends AbstractGraph protected final Profile profile; - public ConnectibleGraph(Profile profile) { - super(); - this.profile = profile; - } - public ConnectibleGraph(Profile profile, AnalysisCallBack callback) { super(callback); this.profile = profile; diff --git a/core/src/main/java/ru/trader/analysis/graph/Crawler.java b/core/src/main/java/ru/trader/analysis/graph/Crawler.java index 7cf77b4..c298865 100644 --- a/core/src/main/java/ru/trader/analysis/graph/Crawler.java +++ b/core/src/main/java/ru/trader/analysis/graph/Crawler.java @@ -3,13 +3,14 @@ package ru.trader.analysis.graph; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ru.trader.analysis.AnalysisCallBack; import ru.trader.analysis.LimitedQueue; import ru.trader.analysis.RouteSpecification; import java.util.*; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; -import java.util.function.Predicate; +import java.util.function.Consumer; public class Crawler { private final static Logger LOG = LoggerFactory.getLogger(Crawler.class); @@ -18,20 +19,23 @@ public class Crawler { private final static int SPLIT_SIZE = 3; protected final Graph graph; - private final Predicate>> onFoundFunc; + protected final CrawlerCallBack callback; + private final Consumer>> onFoundFunc; private final RouteSpecification specification; private T target; private int maxSize; - public Crawler(Graph graph, Predicate>> onFoundFunc) { + public Crawler(Graph graph, Consumer>> onFoundFunc, AnalysisCallBack callback) { this.graph = graph; + this.callback = new CrawlerCallBack(callback); maxSize = graph.getRoot().getLevel(); this.onFoundFunc = onFoundFunc; this.specification = (edge, entry) -> isTarget(edge); } - public Crawler(Graph graph, RouteSpecification specification, Predicate>> onFoundFunc) { + public Crawler(Graph graph, RouteSpecification specification, Consumer>> onFoundFunc, AnalysisCallBack callback) { this.graph = graph; + this.callback = new CrawlerCallBack(callback); maxSize = graph.getRoot().getLevel(); this.onFoundFunc = onFoundFunc; this.specification = specification; @@ -67,6 +71,12 @@ public class Crawler { return updateStates ? specification.updateSpecified(edge, head) : specification.specified(edge, head); } + private void found(List> res){ + callback.found(); + onFoundFunc.accept(res); + + } + public int getMaxSize() { return maxSize; } @@ -95,6 +105,7 @@ public class Crawler { } private void findFast(Vertex s, T target, int count){ + callback.startSearch(s.getEntry(), target, count); Optional> t = graph.getVertex(target); int found = 0; if (t.isPresent()) { @@ -107,6 +118,7 @@ public class Crawler { found = dfs(start(s), t.get().getLevel() + 1, count); } } + callback.endSearch(); LOG.debug("Found {} paths", found); setTarget(null); } @@ -131,6 +143,7 @@ public class Crawler { } public void findMin(Vertex s, T target, int count){ + callback.startSearch(s.getEntry(), target, count); Optional> t = graph.getVertex(target); int found = 0; if (t.isPresent()) { @@ -144,6 +157,7 @@ public class Crawler { } } LOG.debug("Found {} paths", found); + callback.endSearch(); setTarget(null); } @@ -159,24 +173,23 @@ public class Crawler { int found = 0; Vertex source = entry.vertex; LOG.trace("DFS from {} to {}, deep {}, count {}, entry {}", source, target, deep, count, entry); - boolean stop = false; if (deep == source.getLevel()){ for (Edge next : entry.getEdges()) { if (isFound(next, entry, true)){ List> res = getCopyList(entry, next); LOG.debug("Last edge found, path {}", res); found++; - if (!onFoundFunc.test(res)){ - stop = true; - } + found(res); break; } + if (callback.isCancel()) break; } } - if (!stop && found < count){ + if (found < count){ if (deep < source.getLevel() && entry.size() < maxSize-1) { LOG.trace("Search around"); for (Edge edge : entry.getEdges()) { + if (callback.isCancel()) break; if (entry.isSkipped()){ LOG.trace("Is skipped"); break; @@ -197,6 +210,7 @@ public class Crawler { root.sort(); queue.add(root); while (!queue.isEmpty() && count > found){ + if (callback.isCancel()) break; CostTraversalEntry entry = queue.poll(); if (entry.isSkipped()){ LOG.trace("Is skipped"); @@ -210,14 +224,13 @@ public class Crawler { LOG.trace("Search from {} to {}, entry {}", source, target, entry); Iterator> iterator = entry.iterator(); while (iterator.hasNext()){ + if (callback.isCancel()) break; Edge edge = iterator.next(); if (isFound(edge, entry, true)){ List> res = getCopyList(entry, edge); LOG.debug("Last edge found, path {}", res); found++; - if (!onFoundFunc.test(res)){ - break; - } + found(res); } if (entry.isSkipped()){ LOG.trace("Is skipped"); @@ -241,6 +254,7 @@ public class Crawler { PriorityQueue queue = new PriorityQueue<>(); queue.add(root); while (!queue.isEmpty() && count > found){ + if (callback.isCancel()) break; CostTraversalEntry entry = queue.poll(); if (entry.isSkipped()){ LOG.trace("Is skipped"); @@ -253,9 +267,7 @@ public class Crawler { List> res = entry.toEdges(); LOG.debug("Path found {}", res); found++; - if (!onFoundFunc.test(res)){ - break; - } + found(res); if (found >= count) break; } if (entry.isSkipped()){ @@ -272,6 +284,7 @@ public class Crawler { } Iterator> iterator = entry.iterator(); while (iterator.hasNext()){ + if (callback.isCancel()) break; edge = iterator.next(); boolean canDeep = !entry.getTarget().isSingle() && deep < entry.getTarget().getLevel(); if (canDeep || isFound(edge, entry)){ @@ -292,6 +305,7 @@ public class Crawler { root.sort(); queue.add(new CTEntrySupport(root)); while (!(queue.isEmpty() && targetsQueue.isEmpty()) && count > found){ + if (callback.isCancel()) break; int alreadyFound = targetsQueue.size(); CTEntrySupport curr = targetsQueue.peek(); boolean isTarget = curr != null && (queue.isEmpty() || alreadyFound + found >= count || Comparator.naturalOrder().compare(curr, queue.peek()) <= 0); @@ -306,9 +320,7 @@ public class Crawler { List> res = entry.toEdges(); LOG.trace("Path found {}", res); found++; - if (!onFoundFunc.test(res)){ - break; - } + found(res); if (found >= count) break; CTEntrySupport next = targetsQueue.peek(); limit = next != null ? next.entry.getWeight() : Double.NaN; @@ -437,7 +449,7 @@ public class Crawler { } private boolean cancel(){ - if (isCancelled()) return true; + if (isCancelled() || callback.isCancel()) return true; if (root.entry.isSkipped()){ LOG.trace("Root skipped"); if (isSubTask){ diff --git a/core/src/main/java/ru/trader/analysis/graph/CrawlerCallBack.java b/core/src/main/java/ru/trader/analysis/graph/CrawlerCallBack.java new file mode 100644 index 0000000..915a66f --- /dev/null +++ b/core/src/main/java/ru/trader/analysis/graph/CrawlerCallBack.java @@ -0,0 +1,30 @@ +package ru.trader.analysis.graph; + +import ru.trader.analysis.AnalysisCallBack; + +public class CrawlerCallBack { + private final AnalysisCallBack parent; + public final String SEARCH_STAGE = "crawler.stage.search"; + + public CrawlerCallBack(AnalysisCallBack parent) { + this.parent = parent; + } + + public void startSearch(Object from, Object to, int count){ + parent.startStage(SEARCH_STAGE); + parent.print(String.format(parent.getMessage(SEARCH_STAGE), from.toString(), to.toString())); + parent.setMax(count); + } + + public void found(){ + parent.inc(); + } + + public void endSearch(){ + parent.endStage(SEARCH_STAGE); + } + + public boolean isCancel(){ + return parent.isCancel(); + } +} diff --git a/core/src/main/java/ru/trader/core/MarketAnalyzer.java b/core/src/main/java/ru/trader/core/MarketAnalyzer.java index fc5d1c7..f81410d 100644 --- a/core/src/main/java/ru/trader/core/MarketAnalyzer.java +++ b/core/src/main/java/ru/trader/core/MarketAnalyzer.java @@ -21,18 +21,14 @@ public class MarketAnalyzer { private final static Comparator orderComparator = (o1, o2) -> o2.compareTo(o1); public MarketAnalyzer(FilteredMarket market, Profile profile) { - this(market, profile, new MarketAnalyzerCallBack()); + this(market, profile, new AnalysisCallBack()); } - public MarketAnalyzer(FilteredMarket market, Profile profile, MarketAnalyzerCallBack callback) { + public MarketAnalyzer(FilteredMarket market, Profile profile, AnalysisCallBack callback) { this.market = market; - this.callback = callback; + this.callback = new MarketAnalyzerCallBack(callback); this.profile = profile; - this.searcher = new RouteSearcher(new Scorer(market, profile)); - } - - public void setCallback(MarketAnalyzerCallBack callback) { - this.callback = callback; + this.searcher = new RouteSearcher(new Scorer(market, profile), callback); } public Profile getProfile() { @@ -51,7 +47,7 @@ public class MarketAnalyzer { LOG.debug("Get top {}", limit); Collection places = getPlaces(); LimitedQueue top = new LimitedQueue<>(limit, orderComparator); - callback.setMax(places.size()); + callback.start(places.size()); for (Place place : places) { if (callback.isCancel()) break; LOG.trace("Check place {}", place); @@ -59,7 +55,7 @@ public class MarketAnalyzer { top.addAll(orders); callback.inc(); } - callback.onEnd(); + callback.end(); return top; } @@ -105,10 +101,10 @@ public class MarketAnalyzer { } private Collection getOrders(Place place, Collection sellers, double lowProfit) { - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, callback.getParent()); graph.build(place, getPlaces()); List res = new ArrayList<>(20); - callback.setMax(sellers.size()); + callback.start(sellers.size()); for (Vendor vendor : sellers) { if (callback.isCancel()) break; for (Offer sell : vendor.getAllSellOffers()) { @@ -139,12 +135,13 @@ public class MarketAnalyzer { callback.inc(); } res.sort(orderComparator); + callback.end(); return res; } private Collection getOrders(Collection sellers, Collection buyers, double lowProfit) { List res = new ArrayList<>(); - callback.setMax(sellers.size()); + callback.start(sellers.size()); for (Vendor seller : sellers) { if (callback.isCancel()) break; for (Offer sell : seller.getAllSellOffers()) { @@ -170,6 +167,7 @@ public class MarketAnalyzer { callback.inc(); } res.sort(orderComparator); + callback.end(); return res; } @@ -189,7 +187,7 @@ public class MarketAnalyzer { LOG.debug("Get top {}", limit); LimitedQueue top = new LimitedQueue<>(limit); Collection vendors = getVendors(); - callback.setMax(vendors.size()); + callback.start(vendors.size()); Iterator iterator = market.getMarkets(false).iterator(); while (iterator.hasNext()){ Vendor vendor = iterator.next(); @@ -198,7 +196,7 @@ public class MarketAnalyzer { top.addAll(paths); callback.inc(); } - callback.onEndSearch(); + callback.end(); return top; } @@ -233,7 +231,7 @@ public class MarketAnalyzer { public Route getRoute(Collection vendors) { Route res = null; - callback.setMax(vendors.size()); + callback.start(vendors.size()); for (Vendor from : vendors) { //TODO: implement search with constant length Collection paths = searcher.getRoutes(from, vendors); @@ -243,12 +241,12 @@ public class MarketAnalyzer { } callback.inc(); } - callback.onEndSearch(); + callback.end(); return res; } private boolean isInaccessible(Place from, Place to){ - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, callback.getParent()); graph.build(from, getPlaces()); if (!graph.isAccessible(to)){ LOG.trace("Is inaccessible buyer"); @@ -268,4 +266,8 @@ public class MarketAnalyzer { private List getVendors(Place place){ return market.getVendors(place).collect(Collectors.toList()); } + + public MarketAnalyzer changeCallBack(AnalysisCallBack callback){ + return new MarketAnalyzer(market, profile, callback); + } } diff --git a/core/src/main/java/ru/trader/core/MarketAnalyzerCallBack.java b/core/src/main/java/ru/trader/core/MarketAnalyzerCallBack.java index 583f419..171c99e 100644 --- a/core/src/main/java/ru/trader/core/MarketAnalyzerCallBack.java +++ b/core/src/main/java/ru/trader/core/MarketAnalyzerCallBack.java @@ -1,62 +1,34 @@ package ru.trader.core; -import ru.trader.graph.GraphCallBack; -import ru.trader.graph.RouteSearcherCallBack; +import ru.trader.analysis.AnalysisCallBack; public class MarketAnalyzerCallBack { - private volatile boolean cancel = false; - private RouteSearcherCallBack callbackRoute; - private GraphCallBack callbackGraph; + private final AnalysisCallBack parent; + public final String ANALYSIS_STAGE = "market.stage.analysis"; - - protected RouteSearcherCallBack getRouteSearcherCallBackInstance(){ - return new RouteSearcherCallBack(); + public MarketAnalyzerCallBack(AnalysisCallBack parent) { + this.parent = parent; } - protected GraphCallBack getGraphCallBackInstance(){ - return new GraphCallBack<>(); + public void start(int count){ + parent.startStage(ANALYSIS_STAGE); + parent.print(String.format(parent.getMessage(ANALYSIS_STAGE))); + parent.setMax(count); } - public final GraphCallBack onStartGraph(){ - callbackGraph = getGraphCallBackInstance(); - return callbackGraph; + public void inc(){ + parent.inc(); } - public final void onEndGraph(){ - callbackGraph = null; + public void end(){ + parent.endStage(ANALYSIS_STAGE); } - public final RouteSearcherCallBack onStartSearch(){ - callbackRoute = getRouteSearcherCallBackInstance(); - return callbackRoute; + public boolean isCancel(){ + return parent.isCancel(); } - public final void onEndSearch(){ - callbackRoute = null; - onEnd(); + public AnalysisCallBack getParent() { + return parent; } - - protected void onEnd(){} - - public void setMax(long max){} - 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; - } - } - } diff --git a/core/src/main/java/ru/trader/graph/GraphCallBack.java b/core/src/main/java/ru/trader/graph/GraphCallBack.java deleted file mode 100644 index 8e622a6..0000000 --- a/core/src/main/java/ru/trader/graph/GraphCallBack.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.trader.graph; - -import ru.trader.analysis.graph.Vertex; - -public class GraphCallBack> { - - private volatile boolean cancel = false; - - public void onStartBuild(T from){} - public void onEndBuild(){} - - - public void onStartFind(Vertex from, Vertex to){} - public void onFound(){} - public void onEndFind(){} - - - public void setMax(long count){} - public void inc(){} - - public final boolean isCancel() { - return cancel; - } - - public final void cancel(){ - this.cancel = true; - } - -} diff --git a/core/src/main/java/ru/trader/graph/RouteSearcherCallBack.java b/core/src/main/java/ru/trader/graph/RouteSearcherCallBack.java deleted file mode 100644 index 8caf29b..0000000 --- a/core/src/main/java/ru/trader/graph/RouteSearcherCallBack.java +++ /dev/null @@ -1,44 +0,0 @@ -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> callbacks = new LinkedList<>(); - - public final GraphCallBack onStart(){ - GraphCallBack callback = getGraphCallBackInstance(); - if (cancel) return callback; - synchronized (callbacks) { - callbacks.add(callback); - } - return callback; - } - - public final void onEnd( GraphCallBack callback){ - synchronized (callbacks) { - callbacks.remove(callback); - } - } - - protected GraphCallBack 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(); - } - } -} diff --git a/core/src/test/java/ru/trader/analysis/VendorsGraphTest.java b/core/src/test/java/ru/trader/analysis/VendorsGraphTest.java index 4838380..a10e870 100644 --- a/core/src/test/java/ru/trader/analysis/VendorsGraphTest.java +++ b/core/src/test/java/ru/trader/analysis/VendorsGraphTest.java @@ -58,11 +58,11 @@ public class VendorsGraphTest extends Assert { profile.setBalance(100000); profile.setJumps(6); Scorer scorer = new Scorer(fWorld, profile); LOG.info("Build vendors graph"); - VendorsGraph vGraph = new VendorsGraph(scorer); + VendorsGraph vGraph = new VendorsGraph(scorer, new AnalysisCallBack()); vGraph.build(cabreraDock, fWorld.getMarkets(true).collect(Collectors.toList())); LOG.info("Search"); SimpleCollector paths = new SimpleCollector<>(); - Crawler crawler = vGraph.crawler(paths::add); + Crawler crawler = vGraph.crawler(paths::add, new AnalysisCallBack()); // Cabrera Dock -> Transit Wolf 1323 -> Transit Wolf 1325 -> Quimper Ring -> Transit Bhadaba -> Transit Wolf 1325 -> Cabrera Dock] crawler.findMin(cabreraDock, 100); assertEquals(100, paths.get().size()); @@ -189,7 +189,7 @@ public class VendorsGraphTest extends Assert { LOG.info("Start build test"); profile.setBalance(100000); profile.setJumps(6); LOG.info("Build connectible graph"); - ConnectibleGraph vGraph = new ConnectibleGraph<>(profile); + ConnectibleGraph vGraph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); vGraph.build(cabreraDock, fWorld.getMarkets(true).collect(Collectors.toList())); for (Vertex vertex : vGraph.vertexes()) { assertEquals(edgesStat.get(vertex.getEntry().toString()).intValue(), vertex.getEdges().size()); @@ -197,7 +197,7 @@ public class VendorsGraphTest extends Assert { LOG.info("Build vendors graph"); Scorer scorer = new Scorer(fWorld, profile); - vGraph = new VendorsGraph(scorer); + vGraph = new VendorsGraph(scorer, new AnalysisCallBack()); vGraph.build(cabreraDock, fWorld.getMarkets(true).collect(Collectors.toList())); for (Vertex vertex : vGraph.vertexes()) { switch (vertex.getEntry().getName()){ @@ -224,11 +224,11 @@ public class VendorsGraphTest extends Assert { profile.setBalance(100000); profile.setJumps(6); Scorer scorer = new Scorer(fWorld, profile); LOG.info("Build vendors graph"); - VendorsGraph vGraph = new VendorsGraph(scorer); + VendorsGraph vGraph = new VendorsGraph(scorer, new AnalysisCallBack()); vGraph.build(cabreraDock, fWorld.getMarkets(true).collect(Collectors.toList())); LOG.info("Search"); SimpleCollector paths = new SimpleCollector<>(); - Crawler crawler = vGraph.crawler(new LoopRouteSpecification<>(true), paths::add); + Crawler crawler = vGraph.crawler(new LoopRouteSpecification<>(true), paths::add, new AnalysisCallBack()); crawler.findMin(cabreraDock, 100); assertEquals(60, paths.get().size()); Collection vendors = new ArrayList<>(60); diff --git a/core/src/test/java/ru/trader/analysis/graph/CrawlerTest.java b/core/src/test/java/ru/trader/analysis/graph/CrawlerTest.java index 4e7b73c..6a77b4a 100644 --- a/core/src/test/java/ru/trader/analysis/graph/CrawlerTest.java +++ b/core/src/test/java/ru/trader/analysis/graph/CrawlerTest.java @@ -7,6 +7,7 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.trader.TestUtil; +import ru.trader.analysis.AnalysisCallBack; import ru.trader.core.Profile; import ru.trader.core.Ship; @@ -68,12 +69,12 @@ public class CrawlerTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(2); profile.setRefill(false); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4, x5 <-> x6 SimpleCollector paths = new SimpleCollector<>(); - Crawler crawler = new CCrawler<>(graph, paths::add); + Crawler crawler = new CCrawler<>(graph, paths::add, new AnalysisCallBack()); crawler.findMin(x4, 10); TestUtil.assertPaths(paths.get(), PPath.of(x5, x4)); paths.clear(); @@ -97,12 +98,12 @@ public class CrawlerTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(3); profile.setRefill(false); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <-> x3 <-> x2, x5 <-> x6 <-> x7 <-> x8 // x5 <-> x3, x4 <-> x2, x3 <-> x6, x4 <-> x6 SimpleCollector paths = new SimpleCollector<>(); - Crawler crawler = new CCrawler<>(graph, paths::add); + Crawler crawler = new CCrawler<>(graph, paths::add, new AnalysisCallBack()); crawler.findMin(x8, 10); TestUtil.assertPaths(paths.get(), PPath.of(x5, x6, x7, x8)); @@ -161,12 +162,12 @@ public class CrawlerTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(3); profile.setRefill(false); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <- refill -> x3 <- refill -> x2, x5 <-> x6 // x5 <-> x3 <- refill -> x2, x5 <-> x4 <- refill -> x6 SimpleCollector paths = new SimpleCollector<>(); - Crawler crawler = new CCrawler<>(graph, paths::add); + Crawler crawler = new CCrawler<>(graph, paths::add, new AnalysisCallBack()); crawler.findMin(x1, 10); assertTrue(paths.get().isEmpty()); @@ -202,14 +203,14 @@ public class CrawlerTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(4); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <-> x3 - refill -> x2, // x5 <-> x6 <-> x4 <-refill -> x2 // x5 <-> x3 <- refill -> x2 // x5 <-> x4 <- refill -> x6 SimpleCollector paths = new SimpleCollector<>(); - Crawler crawler = new CCrawler<>(graph, paths::add); + Crawler crawler = new CCrawler<>(graph, paths::add, new AnalysisCallBack()); crawler.findMin(x1, 10); assertTrue(paths.get().isEmpty()); @@ -255,14 +256,14 @@ public class CrawlerTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(4); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <-> x3 - refill -> x2, // x5 <-> x6 <-> x4 <-refill -> x2 // x5 <-> x3 <- refill -> x2 // x5 <-> x4 <- refill -> x6 SimpleCollector paths = new SimpleCollector<>(); - CCrawler crawler = new CCrawler<>(graph, paths::add); + CCrawler crawler = new CCrawler<>(graph, paths::add, new AnalysisCallBack()); crawler.setStartFuel(0.3); crawler.findMin(x3, x2); diff --git a/core/src/test/java/ru/trader/analysis/graph/GraphTest.java b/core/src/test/java/ru/trader/analysis/graph/GraphTest.java index 0bd372b..6d3709d 100644 --- a/core/src/test/java/ru/trader/analysis/graph/GraphTest.java +++ b/core/src/test/java/ru/trader/analysis/graph/GraphTest.java @@ -6,6 +6,7 @@ import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ru.trader.analysis.AnalysisCallBack; import ru.trader.core.Profile; import ru.trader.core.Ship; @@ -51,7 +52,7 @@ public class GraphTest extends Assert { profile.setJumps(10); profile.setRefill(false); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 assertFalse(graph.isAccessible(x1)); @@ -76,7 +77,7 @@ public class GraphTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(2); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <-refill-> x3, x5 -> x6 assertFalse(graph.isAccessible(x1)); @@ -121,7 +122,7 @@ public class GraphTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(3);profile.setRefill(false); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <-> x3, x5 <-> x6 assertFalse(graph.isAccessible(x1)); @@ -158,7 +159,7 @@ public class GraphTest extends Assert { Profile profile = new Profile(ship); profile.setJumps(3); profile.setRefill(false); LOG.info("Ship = {}, Jumps = {}", profile.getShip(), profile.getJumps()); - ConnectibleGraph graph = new ConnectibleGraph<>(profile); + ConnectibleGraph graph = new ConnectibleGraph<>(profile, new AnalysisCallBack()); graph.build(x5, entrys); // x5 <-> x4 <-> x3 -> x2, x5 <-> x6 <-> x7 -> x8 // x5 <-> x3, x5 <-> x4 <-> x2, x3 <-> x6, x4 <-> x6 diff --git a/core/src/test/java/ru/trader/analysis/graph/SimpleCollector.java b/core/src/test/java/ru/trader/analysis/graph/SimpleCollector.java index cedca3f..5dfb554 100644 --- a/core/src/test/java/ru/trader/analysis/graph/SimpleCollector.java +++ b/core/src/test/java/ru/trader/analysis/graph/SimpleCollector.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.function.Consumer; import java.util.stream.Collectors; /** @@ -12,9 +13,8 @@ import java.util.stream.Collectors; public class SimpleCollector { private List>> paths = new ArrayList<>(); - public boolean add(List> path){ + public void add(List> path){ paths.add(path); - return true; } public List>> get() { diff --git a/core/src/test/resources/log4j.properties b/core/src/test/resources/log4j.properties index 96fe20c..f2bafda 100644 --- a/core/src/test/resources/log4j.properties +++ b/core/src/test/resources/log4j.properties @@ -4,4 +4,4 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%p: %d{dd.MM.yyyy HH:mm:ss} (%F:%L) - %m%n -#log4j.logger.ru.trader.analysis.graph = TRACE +log4j.logger.ru.trader.analysis.VendorsGraph = DEBUG