Skip to content

Commit

Permalink
Fix incorrect channel mapping by removing channel mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
VoidXH committed Jul 20, 2024
1 parent 94d64eb commit b557c4b
Showing 1 changed file with 1 addition and 82 deletions.
83 changes: 1 addition & 82 deletions Cavern/Filters/Utilities/FilterGraphNodeUtils.Mapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,88 +49,7 @@ public static HashSet<FilterGraphNode> MapGraph(this IEnumerable<FilterGraphNode
/// </summary>
/// <param name="mapping">Node - channel mapping to optimize, virtual channels take negative indices</param>
public static void OptimizeChannelUse(this (FilterGraphNode node, int channel)[] mapping) {
// Trivial: if a member's only parent is before it, don't assign it to a new virtual channel
int lowestChannel = 0;
for (int i = 0; i < mapping.Length; i++) {
if (mapping[i].channel >= 0) {
continue; // Don't touch already assigned physical channels
}

FilterGraphNode node = mapping[i].node;
if (node.Parents.Count == 1) {
FilterGraphNode parent = node.Parents[0];
if (parent.Children.Count == 1 && parent.Children[0] == node) {
for (int j = i - 1; j >= 0; j--) {
if (mapping[j].node == parent) {
mapping[i].channel = mapping[j].channel;
break;
}
}
}
}
if (mapping[i].channel < lowestChannel) { // Erases gaps in virtual channel indices
mapping[i].channel = --lowestChannel;
}
}

int virtualChannels = -mapping.Min(x => x.channel);

// Partition channels to "time" intervals (mapping indices)
(int channel, int first, int last)[] intervals = new (int, int, int)[virtualChannels];
for (int i = 0; i < intervals.Length; i++) {
intervals[i].channel = -1 - i;
intervals[i].first = -1;
}
for (int i = 0; i < mapping.Length; i++) {
int interval = -1 - mapping[i].channel;
if (interval < 0) {
continue; // Virtual channels only
}
if (intervals[interval].first == -1) {
intervals[interval].first = i;
}
intervals[interval].last = i;
}

// True creation is when the channel was separated, and true disappearance is when the channel was merged back
for (int i = 0; i < intervals.Length; i++) {
FilterGraphNode firstNode = mapping[intervals[i].first].node,
lastNode = mapping[intervals[i].last].node;
for (int j = 0; j < mapping.Length; j++) {
if (mapping[j].node.Children.Contains(firstNode)) {
intervals[i].first = j;
}
if (mapping[j].node.Parents.Contains(lastNode)) {
intervals[i].last = j; // Might never be merged, but it's not a problem, we get our thread back faster
}
}
}

// Interval graph optimization problem
Array.Sort(intervals, (a, b) => {
int first = a.first.CompareTo(b.first);
return first != 0 ? first : a.last.CompareTo(b.last);
});

List<int> channelUsedUntil = new List<int>();
for (int i = 0; i < intervals.Length; i++) {
int slots = channelUsedUntil.Count,
needFrom = intervals[i].first;
bool handled = false;
for (int slot = 0; slot < slots; slot++) {
if (channelUsedUntil[slot] <= needFrom) {
intervals[i].channel = -1 - slot;
channelUsedUntil[slot] = intervals[i].last;
handled = true;
break;
}
}

if (!handled) {
channelUsedUntil.Add(intervals[i].last);
intervals[i].channel = -channelUsedUntil.Count;
}
}
// TODO: implement some day
}

/// <summary>
Expand Down

0 comments on commit b557c4b

Please sign in to comment.