Skip to content

Commit 3336cd8

Browse files
Refactoring gap insertion
1 parent a94c818 commit 3336cd8

File tree

1 file changed

+29
-28
lines changed

1 file changed

+29
-28
lines changed

src/Alignment/Pairwise/Internal.hs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ data Direction = DiagArrow | LeftArrow | UpArrow
9898
deriving (Eq, Ord)
9999

100100

101-
data instance U.MVector s Direction = MV_Direction (P.MVector s Word8)
101+
newtype instance U.MVector s Direction = MV_Direction (P.MVector s Word8)
102102

103103

104-
data instance U.Vector Direction = V_Direction (P.Vector Word8)
104+
newtype instance U.Vector Direction = V_Direction (P.Vector Word8)
105105

106106

107107
instance U.Unbox Direction
@@ -279,7 +279,7 @@ measureCharacters
279279
-> f SymbolContext
280280
-> (Ordering, [SymbolContext], [SymbolContext])
281281
measureCharacters lhs rhs =
282-
let f = maybe [] toList
282+
let f = foldMap toList
283283
(b, x, y) = measureNullableCharacters (Just lhs) (Just rhs)
284284
in (b, f x, f y)
285285

@@ -313,8 +313,8 @@ measureNullableCharacters lhs rhs
313313
case comparing (maybe 0 length) lhs rhs of
314314
-- If the inputs are equal length,
315315
-- Then compare by the (arbitary) lexicographical ordering of the median states.
316-
EQ -> let x = maybe [] toList lhs
317-
y = maybe [] toList rhs
316+
EQ -> let x = foldMap toList lhs
317+
y = foldMap toList rhs
318318
f = fmap symbolAlignmentMedian
319319
in case f x `compare` f y of
320320
-- If the input median states have the same ordering,
@@ -465,6 +465,9 @@ insertGaps gap lGaps rGaps meds
465465
rGapCount = totalGaps rGaps
466466
newLength = lGapCount + rGapCount + mLength
467467

468+
ins = insertElement gap gap
469+
del = deleteElement gap gap
470+
468471
xs !> i = maybe (error "Tried to index an empty alignment context when reinserting gaps") (!i) xs
469472

470473
newVector = EV.create $ do
@@ -480,32 +483,30 @@ insertGaps gap lGaps rGaps meds
480483
for_ (IM.toAscList rGaps) $ uncurry (MUV.unsafeWrite rVec)
481484

482485
let align i = do
483-
m <- readSTRef mPtr
484-
let e = meds !> m
485-
let v = coerce e
486-
MV.unsafeWrite mVec i v
487-
modifySTRef mPtr succ
488-
when (isAlign e || isDelete e) $
489-
modifySTRef lGap succ
490-
when (isAlign e || isInsert e) $
491-
modifySTRef rGap succ
492-
493-
let checkRightGapReinsertion i = do
494-
rg <- readSTRef rGap
495-
v <- if rg >= MUV.length rVec then pure 0 else MUV.unsafeRead rVec rg
486+
m <- readSTRef mPtr
487+
let e = meds !> m
488+
let v = coerce e
489+
MV.unsafeWrite mVec i v
490+
modifySTRef mPtr succ
491+
when (isAlign e || isDelete e) $
492+
modifySTRef lGap succ
493+
when (isAlign e || isInsert e) $
494+
modifySTRef rGap succ
495+
496+
let insertGapWith i e gapRef gapVec = do
497+
rg <- readSTRef gapRef
498+
v <- if rg >= MUV.length gapVec then pure 0 else MUV.unsafeRead gapVec rg
496499
if v == 0
497-
then align i
498-
else do MV.unsafeWrite mVec i $ insertElement gap gap
499-
MUV.unsafeWrite rVec rg $ v - 1
500+
then pure False
501+
else do MV.unsafeWrite mVec i e
502+
MUV.unsafeWrite gapVec rg $ v - 1
503+
pure True
500504

501505
for_ [0 .. newLength - 1] $ \i -> do
502-
-- Check if we need to insert a gap from the left char
503-
lg <- readSTRef lGap
504-
v <- if lg >= MUV.length lVec then pure 0 else MUV.unsafeRead lVec lg
505-
if v == 0
506-
then checkRightGapReinsertion i
507-
else do MV.unsafeWrite mVec i $ deleteElement gap gap
508-
MUV.unsafeWrite lVec lg $ v - 1
506+
written <- insertGapWith i ins lGap lVec
507+
unless written $ do
508+
written' <- insertGapWith i del rGap rVec
509+
unless written' $ align i
509510

510511
pure mVec
511512

0 commit comments

Comments
 (0)