Skip to content

Instantly share code, notes, and snippets.

@ppazos
Created January 17, 2026 16:21
Show Gist options
  • Select an option

  • Save ppazos/f97796bdfaad843561b174924772e1e1 to your computer and use it in GitHub Desktop.

Select an option

Save ppazos/f97796bdfaad843561b174924772e1e1 to your computer and use it in GitHub Desktop.
Basic operations to track virtual merge on EHRs
//ehrs = ['A', 'B', 'C', 'D', 'E', 'F']
// TODO: the canonical should be initialized with the identities: A: A, ... so when asking for the canonical of an unmerged EHR, it gives the same EHR back
canonical = [:]
history = []
// A => B : [A: B]
// C => B : [C: B, A: B]
// B => E : [C: E, A: E, B: E]
// merge secondaryEhr into primaryEhr
def merge(secondaryEhr, primaryEhr)
{
// check the secondary isn't an already merged secondary to another primary
if (canonical[secondaryEhr])
{
throw new Exception("Can't merge the secondary "+ secondaryEhr +" to "+ primaryEhr +", it's already merged to "+ canonical[secondaryEhr])
}
// if the primary is a secondary of another merge, can't merge because that "branch" isn't active, only can merge to the primary of another merge or to an independent "branch"
if (canonical[primaryEhr])
{
throw new Exception("Can't merge into primary "+ primaryEhr +" because it's merged to another EHR already: "+ canonical[primaryEhr])
}
// if secondary is canonical (value) of previous merges, change those entries with the new primary
def secondarySecondaries = canonical.findAll { it.value == secondaryEhr }
if (secondarySecondaries)
{
secondarySecondaries.each { entry ->
canonical[entry.key] = primaryEhr
}
}
canonical[secondaryEhr] = primaryEhr
history << [action: 'MERGE', secondary: secondaryEhr, primary: primaryEhr]
}
// unmerges secondaryEhr from primaryEhr
def unmerge(secondaryEhr)
{
// check the secondary was the last merge into the primary
def lastMerge = history.find { it.secondary == secondaryEhr }
if (!lastMerge)
{
throw new Exception("EHR "+ secondaryEhr +" isn't merged")
}
println lastMerge
// secondaryEhr can be the last merge into lastMerge.primary, though that primary can be merged to another primary, so can't unmerge either
def mergedPrimary = history.findAll{ it.secondary == lastMerge.primary }
println mergedPrimary
if (mergedPrimary)
{
throw new Exception("Can't unmerge "+ secondaryEhr +" from "+ lastMerge.primary +": that EHR is merged into another ("+ mergedPrimary[0].primary +"), try unmerging that first")
}
// merges into primaryEhr
def mergeHistory = history.findAll{ it.primary == lastMerge.primary }
println mergeHistory
def lastMergeIntoPrimary = mergeHistory.get(mergeHistory.size() -1)
if (lastMergeIntoPrimary.secondary != secondaryEhr)
{
throw new Exception("Can't unmerge "+ secondaryEhr +": it's not the last merge into "+ lastMerge.primary +", it's "+ lastMergeIntoPrimary.secondary +", try unmerging that first")
}
// removes the canonical for secondaryEhr, keeping it as independent from the primary.
canonical.remove(secondaryEhr)
history << [action: 'UNMERGE', secondary: secondaryEhr, primary: lastMerge.primary]
}
merge('A', 'B')
merge('C', 'B')
merge('B', 'E')
//merge('B', 'F') // can't merge, secondary is a secondary of a previous merge, we can only merge an independent or primary into another primary
merge('E', 'D')
merge('F', 'D')
//merge('D', 'F') // can't merge, primary is a secondary of another merge, we can only merge into an independent or primary EHR
println canonical
println history
unmerge('F')
println canonical
println history
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment