From 2be7469ff153eb44e51f5a8b9b0fad9456384d18 Mon Sep 17 00:00:00 2001 From: tamirms Date: Fri, 17 Sep 2021 19:47:12 +0100 Subject: [PATCH] Speed up path finding dfs by avoiding edges leading to visited nodes (#3933) --- exp/orderbook/dfs.go | 33 +++++++++++++++++++-------------- exp/orderbook/graph.go | 2 ++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/exp/orderbook/dfs.go b/exp/orderbook/dfs.go index 7dc32d560e..c128e6abe8 100644 --- a/exp/orderbook/dfs.go +++ b/exp/orderbook/dfs.go @@ -59,11 +59,21 @@ type searchState interface { ) (xdr.Asset, xdr.Int64, error) } +func contains(list []string, want string) bool { + for i := 0; i < len(list); i++ { + if list[i] == want { + return true + } + } + return false +} + func dfs( ctx context.Context, state searchState, maxPathLength int, - visited []xdr.Asset, + visitedAssets []xdr.Asset, + visitedAssetStrings []string, remainingTerminalNodes int, currentAssetString string, currentAsset xdr.Asset, @@ -73,31 +83,25 @@ func dfs( if err := ctx.Err(); err != nil { return err } - if currentAssetAmount <= 0 { - return nil - } - for _, asset := range visited { - if asset.Equals(currentAsset) { - return nil - } - } - updatedVisitedList := append(visited, currentAsset) + updatedVisitedAssets := append(visitedAssets, currentAsset) + updatedVisitedStrings := append(visitedAssetStrings, currentAssetString) + if state.isTerminalNode(currentAssetString, currentAssetAmount) { state.appendToPaths( - updatedVisitedList, + updatedVisitedAssets, currentAssetString, currentAssetAmount, ) remainingTerminalNodes-- } // abort search if we've visited all destination nodes or if we've exceeded maxPathLength - if remainingTerminalNodes == 0 || len(updatedVisitedList) > maxPathLength { + if remainingTerminalNodes == 0 || len(updatedVisitedStrings) > maxPathLength { return nil } for nextAssetString, offers := range state.edges(currentAssetString) { - if len(offers) == 0 { + if len(offers) == 0 || contains(visitedAssetStrings, nextAssetString) { continue } @@ -113,7 +117,8 @@ func dfs( ctx, state, maxPathLength, - updatedVisitedList, + updatedVisitedAssets, + updatedVisitedStrings, remainingTerminalNodes, nextAssetString, nextAsset, diff --git a/exp/orderbook/graph.go b/exp/orderbook/graph.go index d41b184656..5fe24f18cb 100644 --- a/exp/orderbook/graph.go +++ b/exp/orderbook/graph.go @@ -329,6 +329,7 @@ func (graph *OrderBookGraph) FindPaths( searchState, maxPathLength, []xdr.Asset{}, + []string{}, len(sourceAssets), destinationAssetString, destinationAsset, @@ -380,6 +381,7 @@ func (graph *OrderBookGraph) FindFixedPaths( searchState, maxPathLength, []xdr.Asset{}, + []string{}, len(destinationAssets), sourceAsset.String(), sourceAsset,