Skip to content

Commit

Permalink
Great work to bring memory overhead down and stop OOM exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
smbadiwe committed Nov 12, 2017
1 parent b4e2d54 commit ea48858
Show file tree
Hide file tree
Showing 14 changed files with 196 additions and 139 deletions.
3 changes: 1 addition & 2 deletions MODA.Impl/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ public static IList<int> GetNeighbors(this UndirectedGraph<int> graph, int verte
/// <returns></returns>
public static QueryGraph ToQueryGraph(this IEnumerable<Edge<int>> edges, string graphLabel)
{
var g = new QueryGraph
var g = new QueryGraph(graphLabel)
{
Identifier = graphLabel
};
g.AddVerticesAndEdgeRange(edges);
return g;
Expand Down
3 changes: 1 addition & 2 deletions MODA.Impl/GraphProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@ public static UndirectedGraph<int> LoadGraph(string filename, bool isQueryGraph
UndirectedGraph<int> newGraphInstance;
if (isQueryGraph)
{
newGraphInstance = new QueryGraph
newGraphInstance = new QueryGraph(Path.GetFileNameWithoutExtension(filename))
{
Identifier = Path.GetFileNameWithoutExtension(filename)
};
}
else
Expand Down
29 changes: 16 additions & 13 deletions MODA.Impl/Mapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ public Mapping(SortedList<int, int> function, int subGraphEdgeCount)
/// <summary>
/// Usage is temporary - to help organize stuffs in Algorithm 3
/// </summary>
public int Id;
public int Id { get; set; }

/// <summary>
/// This represents the [f(h) = g] relation. Meaning key is h and value is g.
/// </summary>
public SortedList<int, int> Function;
public SortedList<int, int> Function { get; set; }

/// <summary>
/// Count of all the edges in the input subgraph G that fit the query graph (---Function.Keys).
/// This count is for the induced subgraph
/// </summary>
public int SubGraphEdgeCount;
public int SubGraphEdgeCount { get; set; }

/// <summary>
/// Gets the corresponding image of the <see cref="newlyAddedEdge"/> in the <see cref="inputGraph"/>.
/// Use only for when (InducedSubGraph.EdgeCount > currentQueryGraphEdgeCount)
Expand All @@ -64,7 +64,7 @@ public override bool Equals(object obj)
var other = obj as Mapping;
if (other == null) return false;

if (Id >= 0 && Id != other.Id) return false;
if (Id >= 0 || other.Id >= 0) return Id == other.Id;

int i = 0;
foreach (var func in Function)
Expand All @@ -82,7 +82,9 @@ public override bool Equals(object obj)

public override int GetHashCode()
{
return GetMappedNodes().GetHashCode();
if (Id >= 0) return Id.GetHashCode();

return base.GetHashCode();
}

/// <summary>
Expand All @@ -92,13 +94,14 @@ public override int GetHashCode()
/// <returns></returns>
public string GetMappedNodes()
{
var sb = new StringBuilder();
foreach (var item in Function)
{
sb.AppendFormat("{0}-", item.Value);
}
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
return string.Join("-", Function.Values);
//var sb = new StringBuilder();
//foreach (var item in Function)
//{
// sb.AppendFormat("{0}-", item.Value);
//}
//sb.Remove(sb.Length - 1, 1);
//return sb.ToString();
}

public override string ToString()
Expand Down
34 changes: 23 additions & 11 deletions MODA.Impl/ModaAlgorithms.1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,21 @@ public static Dictionary<QueryGraph, string> Algorithm1_C(UndirectedGraph<int> i
ICollection<Mapping> mappings;
if (qGraph.EdgeCount == (subgraphSize - 1)) // i.e. if qGraph is a tree
{
var inputGraphClone = inputGraph.Clone();
if (UseModifiedGrochow)
{
// Modified Mapping module - MODA and Grockow & Kellis
mappings = Algorithm2_Modified(qGraph, inputGraphClone, numIterations, false);
mappings = Algorithm2_Modified(qGraph, inputGraph, numIterations, false);
}
else
{
var inputGraphClone = inputGraph.Clone();
mappings = Algorithm2(qGraph, inputGraphClone, numIterations, false);
inputGraphClone.Clear();
inputGraphClone = null;
}

// Because we're saving to file, we're better off doing this now
qGraph.RemoveNonApplicableMappings(mappings, inputGraph);
qGraph.RemoveNonApplicableMappings(mappings, inputGraph, false);
treatedNodes.Add(qGraph);
}
else
Expand Down Expand Up @@ -146,16 +148,18 @@ public static Dictionary<QueryGraph, ICollection<Mapping>> Algorithm1(Undirected
ICollection<Mapping> mappings;
if (qGraph.IsTree(subgraphSize))
{
var inputGraphClone = inputGraph.Clone();
if (UseModifiedGrochow)
{
// Modified Mapping module - MODA and Grockow & Kellis
mappings = Algorithm2_Modified(qGraph, inputGraphClone, numIterations, false);
mappings = Algorithm2_Modified(qGraph, inputGraph, numIterations, false);
}
else
{
// Mapping module - MODA and Grockow & Kellis.
var inputGraphClone = inputGraph.Clone();
mappings = Algorithm2(qGraph, inputGraphClone, numIterations, false);
inputGraphClone.Clear();
inputGraphClone = null;
}
}
else
Expand All @@ -177,7 +181,7 @@ public static Dictionary<QueryGraph, ICollection<Mapping>> Algorithm1(Undirected
// Save mappings. Do we need to save to disk? Maybe not!

allMappings.Add(qGraph, mappings);

// Do not call mappings.Clear()
mappings = null;
// Check for complete-ness; if complete, break
if (qGraph.IsComplete(subgraphSize))
Expand All @@ -187,15 +191,20 @@ public static Dictionary<QueryGraph, ICollection<Mapping>> Algorithm1(Undirected
}
qGraph = null;
}
while (true);
while (true);

foreach (var mapping in allMappings)
if (treatedNodes.Count > 0)
{
if (mapping.Key.IsTree(subgraphSize) && !treatedNodes.Contains(mapping.Key))
foreach (var mapping in allMappings)
{
mapping.Key.RemoveNonApplicableMappings(mapping.Value, inputGraph);
if (mapping.Key.IsTree(subgraphSize) && !treatedNodes.Contains(mapping.Key))
{
mapping.Key.RemoveNonApplicableMappings(mapping.Value, inputGraph);
}
}
treatedNodes.Clear();
}
treatedNodes = null;
#endregion
}
else
Expand All @@ -214,10 +223,13 @@ public static Dictionary<QueryGraph, ICollection<Mapping>> Algorithm1(Undirected

qGraph.RemoveNonApplicableMappings(mappings, inputGraph);
allMappings = new Dictionary<QueryGraph, ICollection<Mapping>>(1) { { qGraph, mappings } };

// Do not call mappings.Clear()
mappings = null;
}

return allMappings;
}

}
}
28 changes: 24 additions & 4 deletions MODA.Impl/ModaAlgorithms.2.Modified.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;

namespace MODA.Impl
Expand All @@ -25,7 +26,7 @@ private static ICollection<Mapping> Algorithm2_Modified(QueryGraph queryGraph, U
{
if (numberOfSamples <= 0) numberOfSamples = inputGraph.VertexCount / 3;

var theMappings = new Dictionary<IList<int>, List<Mapping>>(MappingNodesComparer);
var theMappings = new Dictionary<int[], List<Mapping>>(MappingNodesComparer);
var inputGraphDegSeq = inputGraph.GetNodesSortedByDegree(numberOfSamples);

var threadName = Thread.CurrentThread.ManagedThreadId;
Expand All @@ -47,6 +48,10 @@ private static ICollection<Mapping> Algorithm2_Modified(QueryGraph queryGraph, U
{
foreach (var item in mappings)
{
if (item.Value.Count > 1)
{
queryGraph.RemoveNonApplicableMappings(item.Value, inputGraph, getInducedMappingsOnly);
}
//Recall: f(h) = g
List<Mapping> maps;
if (theMappings.TryGetValue(item.Key, out maps))
Expand All @@ -58,8 +63,8 @@ private static ICollection<Mapping> Algorithm2_Modified(QueryGraph queryGraph, U
theMappings[item.Key] = item.Value;
}
}
mappings.Clear();
}
mappings.Clear();
mappings = null;
#endregion
}
Expand All @@ -71,13 +76,28 @@ private static ICollection<Mapping> Algorithm2_Modified(QueryGraph queryGraph, U
queryGraphEdges = null;
inputGraphDegSeq.Clear();
inputGraphDegSeq = null;
var toReturn = new HashSet<Mapping>(theMappings.Values.SelectMany(s => s));
theMappings.Clear();

var toReturn = GetSet(theMappings);
theMappings = null;

Console.WriteLine("\nThread {0}:\tAlgorithm 2: All iteration tasks completed. Number of mappings found: {1}.\n", threadName, toReturn.Count);
return toReturn;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static HashSet<Mapping> GetSet(Dictionary<int[], List<Mapping>> theMappings)
{
var toReturn = new HashSet<Mapping>(theMappings.Values.SelectMany(s => s));
//foreach (var set in theMappings.Keys.ToArray())
//{
// foreach (var item in theMappings[set])
// {
// toReturn.Add(item);
// }
// theMappings.Remove(set);
//}
theMappings.Clear(); // = null;
return toReturn;
}
}
}
14 changes: 10 additions & 4 deletions MODA.Impl/ModaAlgorithms.2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static ICollection<Mapping> Algorithm2(QueryGraph queryGraph, Undirecte

// Do we need this clone? Can't we just remove the node directly from the graph?
// We do need it.
var theMappings = new Dictionary<IList<int>, List<Mapping>>(MappingNodesComparer);
var theMappings = new Dictionary<int[], List<Mapping>>(MappingNodesComparer);
var inputGraphDegSeq = inputGraphClone.GetNodesSortedByDegree(numberOfSamples);
var queryGraphVertices = queryGraph.Vertices.ToArray();
var queryGraphEdges = queryGraph.Edges.ToArray();
Expand All @@ -45,6 +45,10 @@ internal static ICollection<Mapping> Algorithm2(QueryGraph queryGraph, Undirecte
{
foreach (var item in mappings)
{
if (item.Value.Count > 1)
{
queryGraph.RemoveNonApplicableMappings(item.Value, inputGraphClone, getInducedMappingsOnly);
}
//Recall: f(h) = g
List<Mapping> maps;
if (theMappings.TryGetValue(item.Key, out maps))
Expand All @@ -56,23 +60,25 @@ internal static ICollection<Mapping> Algorithm2(QueryGraph queryGraph, Undirecte
theMappings[item.Key] = item.Value;
}
}
mappings.Clear();
}
mappings.Clear();
mappings = null;
#endregion
}
}

//Remove g
inputGraphClone.RemoveVertex(g);
if (inputGraphClone.EdgeCount == 0) break;
}
Array.Clear(queryGraphEdges, 0, queryGraphEdges.Length);
queryGraphEdges = null;
Array.Clear(queryGraphVertices, 0, subgraphSize);
queryGraphVertices = null;
inputGraphDegSeq.Clear();
inputGraphDegSeq = null;

var toReturn = new HashSet<Mapping>(theMappings.Values.SelectMany(s => s));
theMappings.Clear();
var toReturn = GetSet(theMappings);
theMappings = null;

Console.WriteLine("Thread {0}:\tAlgorithm 2: All tasks completed. Number of mappings found: {1}.", threadName, toReturn.Count);
Expand Down
10 changes: 8 additions & 2 deletions MODA.Impl/ModaAlgorithms.3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ private static IList<Mapping> Algorithm3(Dictionary<QueryGraph, ICollection<Mapp
parentQueryGraphEdges.Add(edge);
}
var newEdge = GetEdgeDifference(queryGraph, parentQueryGraph, parentQueryGraphEdges);
parentQueryGraphEdges.Clear();
parentQueryGraphEdges = null;

// if it's NOT a valid edge
if (newEdge.Source == Utils.DefaultEdgeNodeVal)
Expand All @@ -55,14 +57,14 @@ private static IList<Mapping> Algorithm3(Dictionary<QueryGraph, ICollection<Mapp
int oldCount = parentGraphMappings.Count, id = 0, queryGraphEdgeCount = queryGraph.EdgeCount;
var queryGraphEdges = queryGraph.Edges.ToArray();

var groupByGNodes = parentGraphMappings.GroupBy(x => x.Function.Values, MappingNodesComparer); //.ToDictionary(x => x.Key, x => x.ToArray(), MappingNodesComparer);
var groupByGNodes = parentGraphMappings.GroupBy(x => x.Function.Values.ToArray(), MappingNodesComparer); //.ToDictionary(x => x.Key, x => x.ToArray(), MappingNodesComparer);
foreach (var set in groupByGNodes)
{
// function.value (= set of G nodes) are all same here. So build the subgraph here and pass it dowm
var subgraph = Utils.GetSubgraph(inputGraph, set.Key);
foreach (var item in set)
{
item.Id = id;
item.Id = id++;
// Remember, f(h) = g

// if (f(u), f(v)) ϵ G and meets the conditions, add to list
Expand All @@ -73,6 +75,7 @@ private static IList<Mapping> Algorithm3(Dictionary<QueryGraph, ICollection<Mapp
{
list.Add(item);
}
isMapping = null;
}
else if (item.SubGraphEdgeCount > queryGraphEdgeCount)
{
Expand All @@ -86,7 +89,9 @@ private static IList<Mapping> Algorithm3(Dictionary<QueryGraph, ICollection<Mapp
}
}
}
subgraph = null;
}
Array.Clear(queryGraphEdges, 0, queryGraphEdges.Length);
queryGraphEdges = null;
var threadName = System.Threading.Thread.CurrentThread.ManagedThreadId;

Expand All @@ -99,6 +104,7 @@ private static IList<Mapping> Algorithm3(Dictionary<QueryGraph, ICollection<Mapp
{
parentGraphMappings.Add(item);
}
theRest.Clear();
theRest = null;
// Now, remove duplicates
queryGraph.RemoveNonApplicableMappings(list, inputGraph);
Expand Down
Loading

0 comments on commit ea48858

Please sign in to comment.