1{-# OPTIONS_GHC -funbox-strict-fields #-}
2{-# LANGUAGE BangPatterns #-}
16{- This is based on the following implementations:
18 - https://hackage.haskell.org/package/union-find-0.2/docs/src/Data-UnionFind-IO.html
19 - http://yann.regis-gianas.org/public/mini/code_UnionFind.html
21It seems like the OCaml one came first, but I am not sure.
23Compared to the Haskell implementation, the major changes here include:
25 1. No more reallocating PointInfo when changing the weight
26 2. Using the strict modifyIORef
31import Control.Monad ( when )
32import Data.IORef (IORef, modifyIORef', newIORef, readIORef, writeIORef)
33import Data.Word (Word32)
41 Pt (IORef (PointInfo a))
46 = Info {-# UNPACK #-} !(IORef Word32) {-# UNPACK #-} !(IORef a)
47 | Link {-# UNPACK #-} !(Point a)
54fresh :: a -> IO (Point a)
56 do weight <- newIORef 1
57 desc <- newIORef value
58 link <- newIORef (Info weight desc)
62repr :: Point a -> IO (Point a)
64 do pInfo <- readIORef ref
69 Link point1@(Pt ref1) ->
70 do point2 <- repr point1
71 when (point2 /= point1) $
72 do pInfo1 <- readIORef ref1
79 do pInfo <- readIORef ref
85 do link' <- readIORef ref1
94set :: Point a -> a -> IO ()
95set point@(Pt ref) newDesc =
96 do pInfo <- readIORef ref
99 writeIORef descRef newDesc
102 do link' <- readIORef ref1
105 writeIORef descRef newDesc
108 do newPoint <- repr point
112modify :: Point a -> (a -> a) -> IO ()
113modify point@(Pt ref) func =
114 do pInfo <- readIORef ref
117 modifyIORef' descRef func
120 do link' <- readIORef ref1
123 modifyIORef' descRef func
126 do newPoint <- repr point
130union :: Point a -> Point a -> a -> IO ()
132 do point1@(Pt ref1) <- repr p1
133 point2@(Pt ref2) <- repr p2
135 Info w1 d1 <- readIORef ref1
136 Info w2 d2 <- readIORef ref2
139 then writeIORef d1 newDesc
141 weight1 <- readIORef w1
142 weight2 <- readIORef w2
144 let !newWeight = weight1 + weight2
146 if weight1 >= weight2
148 do writeIORef ref2 (Link point1)
149 writeIORef w1 newWeight
150 writeIORef d1 newDesc
152 do writeIORef ref1 (Link point2)
153 writeIORef w2 newWeight
154 writeIORef d2 newDesc
157equivalent :: Point a -> Point a -> IO Bool
164redundant :: Point a -> IO Bool
166 do pInfo <- readIORef ref
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list