Rather than using edge flags to signal deletion, give each block a list of changes that deleted it.
4JR6O4JTKSYR2AU6AMEJDMDYNGTYDGTF7PEPSEGOLUGRYZ5POE4AC
OMRSTWPYKHLIASBIXECZ4YIVF5AUEULGFYZT72YHUIWFFMUJYTMQC
7VXK6DMJTGZBHFJEQY56VPAXZQJDJSWSLKJ5YRSGZSIUYKUGAXFAC
KMLCXD5DQPRT43PFRMVWYPQRZUNW6OR3PI4NKA6G4EAFHTPXV5KAC
EYPCPIP762LUUJ6TLBXU4ZFERH3DEXPYJP65DNCSQTIGFHGW35ZQC
7D7CMNN3DJ5FINFJGQVZXF5X2MYOZHXW3I4RFASPX5SKNTR44WNQC
YGCYIX6C7RUO57HT5F53FIGQYZGGFCFE6YCKC5EUWR2SMUASVKKQC
FWGMIVUZRDI2QWHHR5LLENXWVOLG7G6DGH52ULOV7TPOJYKLGP6AC
AYLFNM5CBTEA3LSXENULW4A66TJG55MNZUCARAMDVOYPBPXKHAOAC
DF5RFSLHH4Y6GBM7MUTRTHXK5WC7FWV6RSEKDYGTKPSAKE2PQBXQC
found := false
// Look for the old edge and update it if it is found.
for _, e := range source.Edges {
if e.Change == introducedBy && e.From == source && e.To == target {
found = true
e.Change = change
e.Flag = ne.Flag
for {
if target.End > ne.To.End {
g.splitBlock(target, ne.To.End)
}
if ne.Flag&EdgeFlagsDeleted != 0 {
// This is a deletion, so we'll add this change to the DeletedBy list if it
// isn't there already.
found := false
for _, h := range target.DeletedBy {
if h == change {
found = true
break
}
}
if !found {
target.DeletedBy = append(target.DeletedBy, change)
}
} else {
// This is an undeletion, so we'll remove the change that did the deletion
// from the DeletedBy list.
for i, h := range target.DeletedBy {
if h == introducedBy {
target.DeletedBy = append(target.DeletedBy[:i], target.DeletedBy[i+1:]...)
break
}
}
}
if target.End == ne.To.End {
var dead, alive int
for _, e := range b.ReverseEdges {
if e.Flag&EdgeFlagsBlock != 0 {
if e.Flag&EdgeFlagsDeleted != 0 {
dead++
} else {
alive++
}
}
}
if dead > 0 && alive == 0 {
deleted[i] = true
}