-- 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 only. The
--   bare-bones library that ships with GHC is ghc-compact.
@package compact
@version 0.1.0.1

module Data.Compact

-- | A <a>Compact</a> contains fully evaluated, pure, immutable data.
--   
--   <a>Compact</a> serves two purposes:
--   
--   <ul>
--   <li>Data stored in a <a>Compact</a> has no garbage collection
--   overhead. The garbage collector considers the whole <a>Compact</a> to
--   be alive if there is a reference to any object within it.</li>
--   <li>A <a>Compact</a> can be serialized, stored, and deserialized
--   again. The serialized data can only be deserialized by the exact
--   binary that created it, but it can be stored indefinitely before
--   deserialization.</li>
--   </ul>
--   
--   Compacts are self-contained, so compacting data involves copying it;
--   if you have data that lives in two <a>Compact</a>s, 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
--   <a>compact</a> or <a>compactWithSharing</a>.
--   
--   When you have a <tt><a>Compact</a> a</tt>, you can get a pointer to
--   the actual object in the region using "GHC.Compact.getCompact". The
--   <a>Compact</a> type serves as handle on the region itself; you can use
--   this handle to add data to a specific <a>Compact</a> with
--   <a>compactAdd</a> or <a>compactAddWithSharing</a> (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 <tt><a>Compact</a> a</tt> if you
--   only have an <tt>a</tt>, 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:
--   
--   <ul>
--   <li>Functions. Compaction only applies to data.</li>
--   <li>Pinned <a>ByteArray#</a> objects cannot be compacted. This is for
--   a good reason: the memory is pinned so that it can be referenced by
--   address (the address might be stored in a C data structure, for
--   example), so we can't make a copy of it to store in the
--   <a>Compact</a>.</li>
--   <li>Objects with mutable pointer fields (e.g. <a>IORef</a>,
--   <a>MutableArray</a>) also cannot be compacted, because subsequent
--   mutation would destroy the property that a compact is
--   self-contained.</li>
--   </ul>
--   
--   If compaction encounters any of the above, a <tt>CompactionFailed</tt>
--   exception will be thrown by the compaction operation.
data Compact a :: * -> *

-- | Compact a value. <i>O(size of unshared data)</i>
--   
--   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 <a>compactWithSharing</a>
--   instead).
--   
--   The object in question must not contain any functions or data with
--   mutable pointers; if it does, <a>compact</a> 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. <i>O(size
--   of data)</i>
--   
--   This is typically about 10x slower than <a>compact</a>, 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, <a>compact</a> 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 <a>Compact</a>. 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 <a>compact</a> with respect to sharing and what
--   data it accepts.
compactAdd :: () => Compact b -> a -> IO Compact a

-- | Add a value to an existing <a>Compact</a>, like <a>compactAdd</a>, but
--   behaving exactly like <a>compactWithSharing</a> with respect to
--   sharing and what data it accepts.
compactAddWithSharing :: () => Compact b -> a -> IO Compact a

-- | Transfer <tt>a</tt> 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 <a>Compact</a>
--   reference. If you have used <a>compactAdd</a>, there may be multiple
--   <a>Compact</a> references into the same compact region. Upholds the
--   property:
--   
--   <pre>
--   inCompact c (getCompact c) == True
--   </pre>
getCompact :: () => Compact a -> a

-- | Check if the second argument is inside the passed <a>Compact</a>.
inCompact :: () => Compact b -> a -> IO Bool

-- | Check if the argument is in any <a>Compact</a>. 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 <a>unsafeReadCompact</a>.
writeCompact :: Typeable a => FilePath -> Compact a -> IO ()

-- | Read out a compact region that was serialized to a file. See
--   <a>hUnsafeGetCompact</a> for safety considerations when using this
--   function.
unsafeReadCompact :: Typeable a => FilePath -> IO (Either String (Compact a))

-- | Write a compact region to a <a>Handle</a>. The compact region can be
--   read out of the handle by using <a>hUnsafeGetCompact</a>.
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:
--   
--   <ul>
--   <li>Our binary representation contains direct pointers to the info
--   tables of objects in the region. This means that the info tables of
--   the receiving process must be laid out in exactly the same way as from
--   the original process; in practice, this means using static linking,
--   using the exact same binary and turning off ASLR. This API does NOT do
--   any safety checking and will probably segfault if you get it wrong. DO
--   NOT run this on untrusted input.</li>
--   <li>You must read out the value at the correct type. We will check
--   this for you and raise an error if the types do not match (this is
--   what the <a>Typeable</a> constraint is for).</li>
--   </ul>
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)
