-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Non-GC'd, contiguous storage for immutable data structures -- -- This package provides user-facing APIs for working with "compact -- regions", which hold a fully evaluated Haskell object graph. These -- regions maintain the invariant that no pointers live inside the struct -- that point outside it, which ensures efficient garbage collection -- without ever reading the structure contents (effectively, it works as -- a manually managed "oldest generation" which is never freed until the -- whole is released). This package is currently highly experimental, but -- we hope it may be useful to some people. It is GHC 8.2 and later only. -- The bare-bones library that ships with GHC is ghc-compact. @package compact @version 0.2.0.0 module Data.Compact -- | A Compact contains fully evaluated, pure, immutable data. -- -- Compact serves two purposes: -- -- -- -- Compacts are self-contained, so compacting data involves copying it; -- if you have data that lives in two Compacts, each will have a -- separate copy of the data. -- -- The cost of compaction is similar to the cost of GC for the same data, -- but it is performed only once. However, because "GHC.Compact.compact" -- does not stop-the-world, retaining internal sharing during the -- compaction process is very costly. The user can choose whether to -- compact or compactWithSharing. -- -- When you have a Compact a, you can get a pointer to -- the actual object in the region using "GHC.Compact.getCompact". The -- Compact type serves as handle on the region itself; you can use -- this handle to add data to a specific Compact with -- compactAdd or compactAddWithSharing (giving you a new -- handle which corresponds to the same compact region, but points to the -- newly added object in the region). At the moment, due to technical -- reasons, it's not possible to get the Compact a if you -- only have an a, so make sure you hold on to the handle as -- necessary. -- -- Data in a compact doesn't ever move, so compacting data is also a way -- to pin arbitrary data structures in memory. -- -- There are some limitations on what can be compacted: -- -- -- -- If compaction encounters any of the above, a CompactionFailed -- exception will be thrown by the compaction operation. data Compact a -- | Compact a value. O(size of unshared data) -- -- If the structure contains any internal sharing, the shared data will -- be duplicated during the compaction process. This will not terminate -- if the structure contains cycles (use compactWithSharing -- instead). -- -- The object in question must not contain any functions or data with -- mutable pointers; if it does, compact will raise an exception. -- In the future, we may add a type class which will help statically -- check if this is the case or not. compact :: () => a -> IO (Compact a) -- | Compact a value, retaining any internal sharing and cycles. O(size -- of data) -- -- This is typically about 10x slower than compact, because it -- works by maintaining a hash table mapping uncompacted objects to -- compacted objects. -- -- The object in question must not contain any functions or data with -- mutable pointers; if it does, compact will raise an exception. -- In the future, we may add a type class which will help statically -- check if this is the case or not. compactWithSharing :: () => a -> IO (Compact a) -- | Add a value to an existing Compact. This will help you avoid -- copying when the value contains pointers into the compact region, but -- remember that after compaction this value will only be deallocated -- with the entire compact region. -- -- Behaves exactly like compact with respect to sharing and what -- data it accepts. compactAdd :: () => Compact b -> a -> IO (Compact a) -- | Add a value to an existing Compact, like compactAdd, but -- behaving exactly like compactWithSharing with respect to -- sharing and what data it accepts. compactAddWithSharing :: () => Compact b -> a -> IO (Compact a) -- | Transfer a into a new compact region, with a preallocated -- size, possibly preserving sharing or not. If you know how big the data -- structure in question is, you can save time by picking an appropriate -- block size for the compact region. compactSized :: () => Int -> Bool -> a -> IO (Compact a) -- | Retrieve a direct pointer to the value pointed at by a Compact -- reference. If you have used compactAdd, there may be multiple -- Compact references into the same compact region. Upholds the -- property: -- --
--   inCompact c (getCompact c) == True
--   
getCompact :: () => Compact a -> a -- | Check if the second argument is inside the passed Compact. inCompact :: () => Compact b -> a -> IO Bool -- | Check if the argument is in any Compact. If true, the value in -- question is also fully evaluated, since any value in a compact region -- must be fully evaluated. isCompact :: () => a -> IO Bool -- | Returns the size in bytes of the compact region. compactSize :: () => Compact a -> IO Word module Data.Compact.Serialize -- | Write a compact region to a file. The resulting file can be read back -- into memory using unsafeReadCompact. writeCompact :: Typeable a => FilePath -> Compact a -> IO () -- | Read out a compact region that was serialized to a file. See -- hUnsafeGetCompact for safety considerations when using this -- function. unsafeReadCompact :: Typeable a => FilePath -> IO (Either String (Compact a)) -- | Write a compact region to a Handle. The compact region can be -- read out of the handle by using hUnsafeGetCompact. hPutCompact :: Typeable a => Handle -> Compact a -> IO () -- | Read out a compact region from a handle. -- -- Compact regions written to handles this way are subject to some -- restrictions: -- -- hUnsafeGetCompact :: forall a. Typeable a => Handle -> IO (Either String (Compact a)) instance Data.Typeable.Internal.Typeable a => Data.Binary.Class.Binary (Data.Compact.Serialize.CompactFile a)