vcache-0.1: hsrc_lib/Database/VCache/Path.hs
module Database.VCache.Path
( vcacheSubdir
, vcacheSubdirM
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Database.VCache.Types
maxPathLen :: Int
maxPathLen = 511 -- key size limit from LMDB 0.9.10
-- | VCache implements a simplified filesystem metaphor. Developers
-- can assign a distinct prefix for all PVars created by the VCache,
-- thus modeling namespaces or subdirectories. Assuming the normal
-- advice of opening the VCache only once in the main module, these
-- prefixes enable transparent, modular decomposition of a VCache
-- application without risk of name collisions.
--
-- VCache is simplistic about this: a prefix is appended directly.
-- If developers use subdir "foo" followed by "bar", the result is
-- the same as "foobar". Separators are left to local conventions.
-- Consider "foo/" and "bar/" to model filesystem subdirectories.
--
-- Paths have a limited maximum size of ~500 bytes, including the
-- final PVar name. A runtime error may be generated for oversized
-- paths. In practice, this should not be an issue.
--
-- Usage Note: Subdirectories allow developers to control risk of
-- namespace collisions between modules or plugins. But they are not
-- intended for domain data! Avoid dynamically creating directories
-- or named PVars based on runtime data. It's better to push most
-- domain logic and schema into the PVar layer, which is subject to
-- rich type safety, GC, potential versioning, and other benefits.
--
vcacheSubdir :: ByteString -> VCache -> VCache
vcacheSubdir p (VCache vs d) =
let d' = subdir d p in
if (BS.length d' > maxPathLen)
then error ("VCache path too long: " ++ show d')
else (VCache vs d')
-- | as vcacheSubdir, but returns Nothing if the path is too large.
vcacheSubdirM :: ByteString -> VCache -> Maybe VCache
vcacheSubdirM p (VCache vs d) =
let d' = subdir d p in
if (BS.length d' > maxPathLen)
then Nothing
else Just (VCache vs d')
subdir :: ByteString -> ByteString -> ByteString
subdir = BS.append
{-# INLINE subdir #-}