Skip to content

Commit

Permalink
Refactor offers graph structure
Browse files Browse the repository at this point in the history
  • Loading branch information
charlie-wasp committed Jun 17, 2019
1 parent 49d6666 commit 4eb04cd
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 44 deletions.
90 changes: 55 additions & 35 deletions src/offers_graph/data_structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ interface IEdgeData {
orderBook: OrderBook;
}

interface IEdge {
vertex: AssetID;
data: IEdgeData;
}

export class OffersGraph {
public static build(offers: Offer[]) {
const graph = new OffersGraph();
Expand All @@ -17,12 +22,10 @@ export class OffersGraph {
return graph;
}

private readonly adjacencyList: Map<AssetID, AssetID[]>;
private readonly edges: Map<string, IEdgeData>;
private readonly edges: Map<AssetID, IEdge[]>;

constructor() {
this.adjacencyList = new Map<AssetID, AssetID[]>();
this.edges = new Map<string, IEdgeData>();
this.edges = new Map<AssetID, IEdge[]>();
}

public build(offers: Offer[]) {
Expand Down Expand Up @@ -68,66 +71,83 @@ export class OffersGraph {
this.sortOrderBooks();
}

public getEdges(from: AssetID) {
return this.edges.get(from);

// return JSON.parse(JSON.stringify(edges), (key, value) => {
// if (key === "capacity") {
// return new BigNumber(value);
// }

// if (key === "orderBook") {
// }

// return value;
// }); // cloning
}

public addEdge(from: AssetID, to: AssetID, data: IEdgeData): void {
if (this.edges.has(`${from}->${to}`)) {
const edge = this.getEdge(from, to);

if (edge) {
throw new Error(`Edge between ${from} and ${to} already exists. Use \`updateEdge\` to overwrite`);
}

this.updateEdge(from, to, data);
const edges = this.edges.get(from);

if (!edges) {
this.edges.set(from, [{ vertex: to, data }]);
} else {
edges.push({ vertex: to, data });
}
}

public updateEdge(from: AssetID, to: AssetID, data: IEdgeData): void {
const adjacent = this.adjacencyList.get(from);
const edge = this.getEdge(from, to);

if (!adjacent) {
this.adjacencyList.set(from, [to]);
} else {
this.adjacencyList.set(from, adjacent.concat(to));
if (!edge) {
return;
}

this.edges.set(`${from}->${to}`, data);
edge.data = data;
}

public getEdgeData(from: AssetID, to: AssetID): IEdgeData | undefined {
return this.edges.get(`${from}->${to}`);
}

public getEdges(from: AssetID): Array<{ vertex: AssetID; data: IEdgeData }> {
const adjacent = this.adjacencyList.get(from);

if (!adjacent) {
return [];
}

return adjacent.map(to => {
const data = this.getEdgeData(from, to);
return { vertex: to, data: data! };
});
const edge = this.getEdge(from, to);
return edge ? edge.data : undefined;
}

public dropEdge(from: AssetID, to: AssetID): void {
this.edges.delete(`${from}->${to}`);
const adjacent = this.adjacencyList.get(from);
const edges = this.edges.get(from);

if (!adjacent) {
if (!edges) {
return;
}

const indexToDrop = adjacent.findIndex(el => el === to);
const indexToDrop = edges.findIndex(e => e.vertex === to);

if (indexToDrop === -1) {
logger.warn("Graph seems to be inconsistent");
return;
}

adjacent.splice(indexToDrop, 1);
this.adjacencyList.set(from, adjacent);
edges.splice(indexToDrop, 1);
this.edges.set(from, edges);
}

private sortOrderBooks() {
this.edges.forEach((data, edge, map) => {
data.orderBook.sort();
map.set(edge, data);
this.edges.forEach(edges => {
edges.forEach(edge => edge.data.orderBook.sort());
});
}

private getEdge(from: AssetID, to: AssetID) {
const edges = this.edges.get(from);

if (!edges) {
return;
}

return edges.find(e => e.vertex === to);
}
}
20 changes: 11 additions & 9 deletions src/offers_graph/path_finder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@ export class PathFinder {
// fan out
const edges = this.graph.getEdges(nextAsset);

if (edges.length !== 0) {
for (const {
vertex,
data: { capacity, orderBook }
} of edges) {
if (capacity.gte(amountIn)) {
const amountOut = orderBook.buy(amountIn);
find(vertex, amountOut, currentPath.concat(nextAsset));
}
if (!edges) {
return;
}

for (const {
vertex,
data: { capacity, orderBook }
} of edges) {
if (capacity.gte(amountIn)) {
const amountOut = orderBook.buy(amountIn);
find(vertex, amountOut, currentPath.concat(nextAsset));
}
}
};
Expand Down

0 comments on commit 4eb04cd

Please sign in to comment.