Archived
0

improve search with combine specification

This commit is contained in:
iMoHax
2015-08-28 15:25:54 +03:00
parent d8b09cc837
commit 5c1a31f992
3 changed files with 54 additions and 9 deletions

View File

@@ -6,6 +6,10 @@ import ru.trader.analysis.graph.Traversal;
public interface RouteSpecification<T> { public interface RouteSpecification<T> {
public boolean specified(Edge<T> edge, Traversal<T> entry); public boolean specified(Edge<T> edge, Traversal<T> entry);
public default int lastFound(Edge<T> edge, Traversal<T> entry){
return specified(edge, entry) ? 0 : matchCount();
}
public default int matchCount(){return 1;}
public default boolean updateMutated(){return false;} public default boolean updateMutated(){return false;}
public default boolean mutable(){return false;} public default boolean mutable(){return false;}
public default void update(Traversal<T> entry){} public default void update(Traversal<T> entry){}
@@ -17,6 +21,16 @@ public interface RouteSpecification<T> {
return RouteSpecification.this.specified(edge, entry) && other.specified(edge, entry); return RouteSpecification.this.specified(edge, entry) && other.specified(edge, entry);
} }
@Override
public int lastFound(Edge<T> edge, Traversal<T> entry) {
return RouteSpecification.this.lastFound(edge, entry) + other.lastFound(edge, entry);
}
@Override
public int matchCount() {
return RouteSpecification.this.matchCount() + other.matchCount();
}
@Override @Override
public boolean updateMutated() { public boolean updateMutated() {
return RouteSpecification.this.updateMutated() || other.updateMutated(); return RouteSpecification.this.updateMutated() || other.updateMutated();
@@ -42,6 +56,16 @@ public interface RouteSpecification<T> {
return RouteSpecification.this.specified(edge, entry) || other.specified(edge, entry); return RouteSpecification.this.specified(edge, entry) || other.specified(edge, entry);
} }
@Override
public int lastFound(Edge<T> edge, Traversal<T> entry) {
return Math.min(RouteSpecification.this.lastFound(edge, entry), other.lastFound(edge, entry));
}
@Override
public int matchCount() {
return Math.min(RouteSpecification.this.matchCount(), other.matchCount());
}
@Override @Override
public boolean updateMutated() { public boolean updateMutated() {
return RouteSpecification.this.updateMutated() || other.updateMutated(); return RouteSpecification.this.updateMutated() || other.updateMutated();

View File

@@ -20,30 +20,46 @@ public class RouteSpecificationByTargets<T> implements RouteSpecification<T> {
@Override @Override
public boolean specified(Edge<T> edge, Traversal<T> entry) { public boolean specified(Edge<T> edge, Traversal<T> entry) {
return all ? containsAll(edge, entry) == 0 : containsAny(edge, entry) == 0;
}
@Override
public int lastFound(Edge<T> edge, Traversal<T> entry) {
return all ? containsAll(edge, entry) : containsAny(edge, entry); return all ? containsAll(edge, entry) : containsAny(edge, entry);
} }
private boolean containsAll(Edge<T> edge, Traversal<T> entry) { @Override
public int matchCount() {
return all ? targets.size() : 1;
}
private int containsAll(Edge<T> edge, Traversal<T> entry) {
T obj = edge.getTarget().getEntry(); T obj = edge.getTarget().getEntry();
Collection<T> set = new ArrayList<>(targets.size()); Collection<T> set = new ArrayList<>(targets.size());
set.add(obj); set.add(obj);
entry.routeIterator().forEachRemaining(e -> set.add(e.getTarget().getEntry())); entry.routeIterator().forEachRemaining(e -> set.add(e.getTarget().getEntry()));
return set.containsAll(targets); int last = targets.size();
for (T target : targets) {
if (set.contains(target)){
last--;
}
}
return last;
} }
private boolean containsAny(Edge<T> edge, Traversal<T> entry) { private int containsAny(Edge<T> edge, Traversal<T> entry) {
T obj = edge.getTarget().getEntry(); T obj = edge.getTarget().getEntry();
if (targets.contains(obj)) return true; if (targets.contains(obj)) return 0;
if (targetOnly){ if (targetOnly){
return false; return 1;
} }
Iterator<Edge<T>> iterator = entry.routeIterator(); Iterator<Edge<T>> iterator = entry.routeIterator();
while (iterator.hasNext()){ while (iterator.hasNext()){
if (targets.contains(iterator.next().getTarget().getEntry())){ if (targets.contains(iterator.next().getTarget().getEntry())){
return true; return 0;
} }
} }
return false; return 1;
} }
public static <T> RouteSpecificationByTargets<T> all(Collection<T> targets){ public static <T> RouteSpecificationByTargets<T> all(Collection<T> targets){

View File

@@ -65,6 +65,10 @@ public class Crawler<T> {
return specification.specified(edge, head); return specification.specified(edge, head);
} }
protected int lastFound(Edge<T> edge, Traversal<T> head){
return specification.lastFound(edge, head);
}
private void updateState(Traversal<T> entry){ private void updateState(Traversal<T> entry){
if (specification.mutable()){ if (specification.mutable()){
specification.update(entry); specification.update(entry);
@@ -511,8 +515,9 @@ public class Crawler<T> {
CostTraversalEntry entry = curr.entry; CostTraversalEntry entry = curr.entry;
if (skip()) continue; if (skip()) continue;
LOG.trace("Check edge {}, entry {}, weight {}, curr {}", edge, entry, entry.weight, curr); LOG.trace("Check edge {}, entry {}, weight {}, curr {}", edge, entry, entry.weight, curr);
boolean isTarget = isFound(edge, entry); int lastFound = lastFound(edge, entry);
boolean canDeep = !entry.getTarget().isSingle() && deep < entry.getTarget().getLevel() && entry.size() < maxSize-1; boolean isTarget = lastFound == 0;
boolean canDeep = !entry.getTarget().isSingle() && deep < entry.getTarget().getLevel() && entry.size()+lastFound < maxSize;
if (canDeep || isTarget){ if (canDeep || isTarget){
CostTraversalEntry nextEntry = travers(entry, edge); CostTraversalEntry nextEntry = travers(entry, edge);
if (canDeep){ if (canDeep){