public static void AddOrUpdateEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId) { uint data1 = ContractedEdgeDataSerializer.Serialize(weight, direction); bool hasExistingEdge = false; bool hasExistingEdgeOnlySameDirection = true; if ((int)graph.UpdateEdge(vertex1, vertex2, (Func <uint[], bool>)(data => { hasExistingEdge = true; if (ContractedEdgeDataSerializer.HasDirection(data[0], direction)) { return((double)weight < (double)ContractedEdgeDataSerializer.DeserializeWeight(data[0])); } hasExistingEdgeOnlySameDirection = false; return(false); }), new uint[1] { data1 }, contractedId) != -1) { return; } if (!hasExistingEdge) { int num1 = (int)graph.AddEdge(vertex1, vertex2, data1, contractedId); } else { if (hasExistingEdgeOnlySameDirection) { return; } bool flag1 = false; float weight1 = float.MaxValue; uint metaData1 = uint.MaxValue; bool flag2 = false; float weight2 = float.MaxValue; uint metaData2 = uint.MaxValue; if (!direction.HasValue || direction.Value) { flag1 = true; weight1 = weight; metaData1 = contractedId; } if (!direction.HasValue || !direction.Value) { flag2 = true; weight2 = weight; metaData2 = contractedId; } DirectedMetaGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator.MoveNext()) { if ((int)edgeEnumerator.Neighbour == (int)vertex2) { float weight3; bool? direction1; uint contractedId1; ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0, edgeEnumerator.MetaData0, out weight3, out direction1, out contractedId1); if ((!direction1.HasValue || direction1.Value) && (double)weight3 < (double)weight1) { weight1 = weight3; flag1 = true; metaData1 = contractedId1; } if ((!direction1.HasValue || !direction1.Value) && (double)weight3 < (double)weight2) { weight2 = weight3; flag2 = true; metaData2 = contractedId1; } } } graph.RemoveEdge(vertex1, vertex2); if (flag1 & flag2 && (double)weight1 == (double)weight2 && (int)metaData1 == (int)metaData2) { int num2 = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight1, new bool?()), metaData1); } else { if (flag1) { int num3 = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight1, new bool?(true)), metaData1); } if (!flag2) { return; } int num4 = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight2, new bool?(false)), metaData2); } } }
/// <summary> /// Add or update edge. /// </summary> /// <returns></returns> public static void AddOrUpdateEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId, float distance, float time) { var current = ContractedEdgeDataSerializer.Serialize(weight, direction); var hasExistingEdge = false; var hasExistingEdgeOnlySameDirection = true; if (graph.UpdateEdge(vertex1, vertex2, (data) => { hasExistingEdge = true; if (ContractedEdgeDataSerializer.HasDirection(data[0], direction)) { // has the same direction. if (weight < ContractedEdgeDataSerializer.DeserializeWeight(data[0])) { // the weight is better, just update. return(true); } return(false); } hasExistingEdgeOnlySameDirection = false; return(false); }, new uint[] { current }, ContractedEdgeDataSerializer.SerializeMetaAugmented(contractedId, distance, time)) != Constants.NO_EDGE) { // updating the edge succeeded. return; } if (!hasExistingEdge) { // no edge exists yet. graph.AddEdge(vertex1, vertex2, new uint[] { current }, ContractedEdgeDataSerializer.SerializeMetaAugmented( contractedId, distance, time)); return; } else if (hasExistingEdgeOnlySameDirection) { // there is an edge already but it has a better weight. return; } else { // see what's there and update if needed. var forward = false; var forwardWeight = float.MaxValue; var forwardContractedId = uint.MaxValue; var forwardTime = float.MaxValue; var forwardDistance = float.MaxValue; var backward = false; var backwardWeight = float.MaxValue; var backwardContractedId = uint.MaxValue; var backwardTime = float.MaxValue; var backwardDistance = float.MaxValue; if (direction == null || direction.Value) { forward = true; forwardWeight = weight; forwardContractedId = contractedId; forwardTime = time; forwardDistance = distance; } if (direction == null || !direction.Value) { backward = true; backwardWeight = weight; backwardContractedId = contractedId; backwardTime = time; backwardDistance = distance; } var edgeEnumerator = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator.MoveNext()) { if (edgeEnumerator.Neighbour == vertex2) { float localWeight; bool? localDirection; ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out localWeight, out localDirection); uint localContractedId; float localTime; float localDistance; ContractedEdgeDataSerializer.DeserializeMetaAgumented(edgeEnumerator.MetaData, out localContractedId, out localDistance, out localTime); if (localDirection == null || localDirection.Value) { if (localWeight < forwardWeight) { forwardWeight = localWeight; forward = true; forwardContractedId = localContractedId; forwardTime = localTime; forwardDistance = localDistance; } } if (localDirection == null || !localDirection.Value) { if (localWeight < backwardWeight) { backwardWeight = localWeight; backward = true; backwardContractedId = localContractedId; backwardDistance = localDistance; backwardTime = localTime; } } } } graph.RemoveEdge(vertex1, vertex2); if (forward && backward && forwardWeight == backwardWeight && forwardContractedId == backwardContractedId) { // add one bidirectional edge. graph.AddEdge(vertex1, vertex2, forwardWeight, null, forwardContractedId, forwardDistance, forwardTime); //graph.AddEdge(vertex1, vertex2, // ContractedEdgeDataSerializer.Serialize(forwardWeight, null), forwardContractedId); } else { // add two unidirectional edges if needed. if (forward) { // there is a forward edge. graph.AddEdge(vertex1, vertex2, forwardWeight, true, forwardContractedId, forwardDistance, forwardTime); //graph.AddEdge(vertex1, vertex2, // ContractedEdgeDataSerializer.Serialize(forwardWeight, true), forwardContractedId); } if (backward) { // there is a backward edge. graph.AddEdge(vertex1, vertex2, backwardWeight, false, backwardContractedId, backwardDistance, backwardTime); } } } }