summaryrefslogtreecommitdiff
path: root/src-3.0/GF/Source/SharedString.hs
blob: 732873fe6e0ae14b8e6d58d87f92bcc23ad2f188 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module GF.Source.SharedString (shareString) where

import Data.Map as M
import Data.IORef
import qualified Data.ByteString.Char8 as BS
import System.IO.Unsafe (unsafePerformIO)

{-# NOINLINE stringPoolRef #-}
stringPoolRef :: IORef (M.Map BS.ByteString BS.ByteString)
stringPoolRef = unsafePerformIO $ newIORef M.empty

{-# NOINLINE shareString #-}
shareString :: BS.ByteString -> BS.ByteString
shareString s = unsafePerformIO $ do
  stringPool <- readIORef stringPoolRef
  case M.lookup s stringPool of
    Just s' -> return s'
    Nothing -> do let s' = BS.copy s
                  writeIORef stringPoolRef $! M.insert s' s' stringPool
                  return s'