From 11987749fc6e6d3e53ea737d46d5ab13a16faeb8 Mon Sep 17 00:00:00 2001 From: James Crayne Date: Sat, 28 Sep 2019 13:43:29 -0400 Subject: Factor out some new libraries word64-map: Data.Word64Map network-addr: Network.Address tox-crypto: Crypto.Tox lifted-concurrent: Control.Concurrent.Lifted.Instrument Control.Concurrent.Async.Lifted.Instrument psq-wrap: Data.Wrapper.PSQInt Data.Wrapper.PSQ minmax-psq: Data.MinMaxPSQ tasks: Control.Concurrent.Tasks kad: Network.Kademlia Network.Kademlia.Bootstrap Network.Kademlia.Routing Network.Kademlia.CommonAPI Network.Kademlia.Persistence Network.Kademlia.Search --- psq-wrap/src/Data/Wrapper/PSQ.hs | 91 +++++++++++++++++++++++++++++++++++++ psq-wrap/src/Data/Wrapper/PSQInt.hs | 53 +++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 psq-wrap/src/Data/Wrapper/PSQ.hs create mode 100644 psq-wrap/src/Data/Wrapper/PSQInt.hs (limited to 'psq-wrap/src/Data') diff --git a/psq-wrap/src/Data/Wrapper/PSQ.hs b/psq-wrap/src/Data/Wrapper/PSQ.hs new file mode 100644 index 00000000..4fdeec67 --- /dev/null +++ b/psq-wrap/src/Data/Wrapper/PSQ.hs @@ -0,0 +1,91 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE ConstraintKinds #-} +module Data.Wrapper.PSQ +#if 0 + ( module Data.Wrapper.PSQ , module Data.PSQueue ) where + +import Data.PSQueue hiding (foldr, foldl) +import qualified Data.PSQueue as PSQueue + +type PSQKey k = (Ord k) + +-- | Wrapper over PSQueue-style foldr to implement a psqueues-style interface. +fold' :: (Ord k, Ord p) => (k -> p -> () -> a -> a) -> a -> PSQ k p -> a +fold' f a q = PSQueue.foldr f' a q + where + f' (k :-> prio) x = f k prio () x + +#else + ( module Data.Wrapper.PSQ , module HashPSQ ) where + +-- import Data.OrdPSQ as OrdPSQ hiding (insert, map, singleton, minView) +-- import qualified Data.OrdPSQ as OrdPSQ + +import Data.Hashable +import qualified Data.HashPSQ as Q + ;import Data.HashPSQ as HashPSQ hiding (insert, map, minView, + singleton) +import Data.Time.Clock.POSIX (POSIXTime) + +-- type PSQ' k p v = HashPSQ k p v +type PSQ' = HashPSQ +type PSQ k p = PSQ' k p () + +type Binding' k p v = (k,p,v) +type Binding k p = Binding' k p () + +type PSQKey k = (Hashable k, Ord k) + +pattern (:->) :: k -> p -> Binding k p +pattern k :-> p <- (k,p,_) where k :-> p = (k,p,()) + +-- I tried defining (::->) :: (k,v) -> p -> Binding' k p v +-- but no luck... +pattern Binding :: k -> v -> p -> Binding' k p v +pattern Binding k v p <- (k,p,v) where Binding k v p = (k,p,v) + +key :: (k,p,v) -> k +key (k,p,v) = k +{-# INLINE key #-} + +prio :: (k,p,v) -> p +prio (k,p,v) = p +{-# INLINE prio #-} + +insert :: (PSQKey k, Ord p) => k -> p -> PSQ k p -> PSQ k p +insert k p q = Q.insert k p () q +{-# INLINE insert #-} + +insert' :: (PSQKey k, Ord p) => k -> v -> p -> PSQ' k p v -> PSQ' k p v +insert' k v p q = Q.insert k p v q +{-# INLINE insert' #-} + +insertWith :: (PSQKey k, Ord p) => (p -> p -> p) -> k -> p -> PSQ k p -> PSQ k p +insertWith f k p0 q = snd $ Q.alter f' k q + where + f' (Just (p,())) = ((),Just (f p0 p, ())) + f' Nothing = ((),Just (p0,())) +{-# INLINE insertWith #-} + +singleton :: (PSQKey k, Ord p) => k -> p -> PSQ k p +singleton k p = Q.singleton k p () +{-# INLINE singleton #-} + +singleton' :: (PSQKey k, Ord p) => k -> v -> p -> PSQ' k p v +singleton' k v p = Q.singleton k p v +{-# INLINE singleton' #-} + + +minView :: (PSQKey k, Ord p) => PSQ' k p v -> Maybe (Binding' k p v, PSQ' k p v) +minView q = fmap (\(k,p,v,q') -> (Binding k v p, q')) $ Q.minView q +{-# INLINE minView #-} + + +-- | Utility to convert a 'POSIXTime' delta into microseconds suitable for +-- passing to 'threadDelay'. +toMicroseconds :: POSIXTime -> Int +toMicroseconds = round . (* 1000) . (* 1000) + + +#endif diff --git a/psq-wrap/src/Data/Wrapper/PSQInt.hs b/psq-wrap/src/Data/Wrapper/PSQInt.hs new file mode 100644 index 00000000..5badb8b2 --- /dev/null +++ b/psq-wrap/src/Data/Wrapper/PSQInt.hs @@ -0,0 +1,53 @@ +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE ConstraintKinds #-} +module Data.Wrapper.PSQInt +#if 0 + ( module Data.Wrapper.PSQInt , module Data.PSQueue ) where + +import Data.PSQueue hiding (foldr, foldl, PSQ) +import qualified Data.PSQueue as PSQueue + +type PSQ p = PSQueue.PSQ Int p + +-- | Wrapper over PSQueue-style foldr to implement a psqueues-style interface. +fold' :: (Ord p) => (Int -> p -> () -> a -> a) -> a -> PSQ p -> a +fold' f a q = PSQueue.foldr f' a q + where + f' (k :-> prio) x = f k prio () x + +#else + ( module Data.Wrapper.PSQInt + , module IntPSQ + , module Data.Wrapper.PSQ + ) where + +import Data.Wrapper.PSQ (Binding, pattern (:->), key, prio, toMicroseconds) + +import Data.IntPSQ as IntPSQ hiding (insert, map, singleton, minView) +import qualified Data.IntPSQ as Q + +type PSQ p = IntPSQ p () + +type PSQKey = () + +insert :: (Ord p) => Int -> p -> PSQ p -> PSQ p +insert k p q = Q.insert k p () q +{-# INLINE insert #-} + +insertWith :: (Ord p) => (p -> p -> p) -> Int -> p -> PSQ p -> PSQ p +insertWith f k p0 q = snd $ Q.alter f' k q + where + f' (Just (p,())) = ((),Just (f p0 p, ())) + f' Nothing = ((),Nothing) +{-# INLINE insertWith #-} + +singleton :: (Ord p) => Int -> p -> PSQ p +singleton k p = Q.singleton k p () +{-# INLINE singleton #-} + +minView :: (Ord p) => PSQ p -> Maybe (Binding Int p, PSQ p) +minView q = fmap (\(k,p,(),q') -> (k :-> p, q')) $ Q.minView q +{-# INLINE minView #-} + +#endif -- cgit v1.2.3