parsePOSIXTime ByteString conversion

Some easy (though tiny) speed wins.

Sponsored-by: Luke T. Shumaker on Patreon
This commit is contained in:
Joey Hess 2025-01-22 16:41:06 -04:00
parent d3de3c28eb
commit 77e9781ae2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
13 changed files with 22 additions and 16 deletions

View file

@ -108,6 +108,7 @@ import Utility.HumanTime
import Utility.TimeStamp import Utility.TimeStamp
import Utility.FileMode import Utility.FileMode
import qualified Utility.RawFilePath as R import qualified Utility.RawFilePath as R
import qualified Utility.FileIO as F
import qualified System.FilePath.ByteString as P import qualified System.FilePath.ByteString as P
import System.PosixCompat.Files (isSymbolicLink, linkCount) import System.PosixCompat.Files (isSymbolicLink, linkCount)
@ -1086,7 +1087,7 @@ writeContentRetentionTimestamp key rt t = do
readContentRetentionTimestamp :: RawFilePath -> Annex (Maybe POSIXTime) readContentRetentionTimestamp :: RawFilePath -> Annex (Maybe POSIXTime)
readContentRetentionTimestamp rt = readContentRetentionTimestamp rt =
liftIO $ join <$> tryWhenExists liftIO $ join <$> tryWhenExists
(parsePOSIXTime <$> readFile (fromRawFilePath rt)) (parsePOSIXTime <$> F.readFile' (toOsPath rt))
{- Checks if the retention timestamp is in the future, if so returns {- Checks if the retention timestamp is in the future, if so returns
- Nothing. - Nothing.

View file

@ -21,6 +21,7 @@ import qualified Annex
import Utility.TimeStamp import Utility.TimeStamp
import Data.ByteString.Builder import Data.ByteString.Builder
import qualified Data.ByteString as B
import qualified Data.Attoparsec.ByteString.Lazy as A import qualified Data.Attoparsec.ByteString.Lazy as A
currentVectorClock :: Annex CandidateVectorClock currentVectorClock :: Annex CandidateVectorClock
@ -76,7 +77,7 @@ formatVectorClock (VectorClock t) = show t
buildVectorClock :: VectorClock -> Builder buildVectorClock :: VectorClock -> Builder
buildVectorClock = string7 . formatVectorClock buildVectorClock = string7 . formatVectorClock
parseVectorClock :: String -> Maybe VectorClock parseVectorClock :: B.ByteString -> Maybe VectorClock
parseVectorClock t = VectorClock <$> parsePOSIXTime t parseVectorClock t = VectorClock <$> parsePOSIXTime t
vectorClockParser :: A.Parser VectorClock vectorClockParser :: A.Parser VectorClock

View file

@ -12,12 +12,13 @@ import Data.Time.Clock.POSIX
import Types.VectorClock import Types.VectorClock
import Utility.Env import Utility.Env
import Utility.TimeStamp import Utility.TimeStamp
import Utility.FileSystemEncoding
startVectorClock :: IO (IO CandidateVectorClock) startVectorClock :: IO (IO CandidateVectorClock)
startVectorClock = go =<< getEnv "GIT_ANNEX_VECTOR_CLOCK" startVectorClock = go =<< getEnv "GIT_ANNEX_VECTOR_CLOCK"
where where
go Nothing = timebased go Nothing = timebased
go (Just s) = case parsePOSIXTime s of go (Just s) = case parsePOSIXTime (encodeBS s) of
Just t -> return (pure (CandidateVectorClock t)) Just t -> return (pure (CandidateVectorClock t))
Nothing -> timebased Nothing -> timebased
-- Avoid using fractional seconds in the CandidateVectorClock. -- Avoid using fractional seconds in the CandidateVectorClock.

View file

@ -136,13 +136,13 @@ readDaemonStatusFile file = parse <$> newDaemonStatus <*> readFile file
where where
parse status = foldr parseline status . lines parse status = foldr parseline status . lines
parseline line status parseline line status
| key == "lastRunning" = parseval parsePOSIXTime $ \v -> | key == "lastRunning" = parseval (parsePOSIXTime . encodeBS) $ \v ->
status { lastRunning = Just v } status { lastRunning = Just v }
| key == "scanComplete" = parseval readish $ \v -> | key == "scanComplete" = parseval readish $ \v ->
status { scanComplete = v } status { scanComplete = v }
| key == "sanityCheckRunning" = parseval readish $ \v -> | key == "sanityCheckRunning" = parseval readish $ \v ->
status { sanityCheckRunning = v } status { sanityCheckRunning = v }
| key == "lastSanityCheck" = parseval parsePOSIXTime $ \v -> | key == "lastSanityCheck" = parseval (parsePOSIXTime . encodeBS) $ \v ->
status { lastSanityCheck = Just v } status { lastSanityCheck = Just v }
| otherwise = status -- unparsable line | otherwise = status -- unparsable line
where where

View file

@ -702,7 +702,7 @@ getStartTime u = do
liftIO $ catchDefaultIO Nothing $ do liftIO $ catchDefaultIO Nothing $ do
timestamp <- modificationTime <$> R.getFileStatus f timestamp <- modificationTime <$> R.getFileStatus f
let fromstatus = Just (realToFrac timestamp) let fromstatus = Just (realToFrac timestamp)
fromfile <- parsePOSIXTime <$> readFile (fromRawFilePath f) fromfile <- parsePOSIXTime <$> F.readFile' (toOsPath f)
return $ if matchingtimestamp fromfile fromstatus return $ if matchingtimestamp fromfile fromstatus
then Just timestamp then Just timestamp
else Nothing else Nothing

View file

@ -373,4 +373,4 @@ inodeCaches locs repo = guardSafeForLsFiles repo $ do
mkInodeCache mkInodeCache
<$> (readish =<< M.lookup "ino:" m) <$> (readish =<< M.lookup "ino:" m)
<*> (readish =<< M.lookup "size:" m) <*> (readish =<< M.lookup "size:" m)
<*> (parsePOSIXTime =<< (replace ":" "." <$> M.lookup "mtime:" m)) <*> (parsePOSIXTime =<< (encodeBS . replace ":" "." <$> M.lookup "mtime:" m))

View file

@ -80,5 +80,5 @@ parseAdjustLog l =
"1" -> Just True "1" -> Just True
"0" -> Just False "0" -> Just False
_ -> Nothing _ -> Nothing
t <- parsePOSIXTime ts t <- parsePOSIXTime (encodeBS ts)
return (b, t) return (b, t)

View file

@ -320,7 +320,7 @@ readTransferInfo mpid s = TransferInfo
bits = splitc ' ' firstline bits = splitc ' ' firstline
numbits = length bits numbits = length bits
time = if numbits > 0 time = if numbits > 0
then Just <$> parsePOSIXTime =<< headMaybe bits then Just <$> parsePOSIXTime . encodeBS =<< headMaybe bits
else pure Nothing -- not failure else pure Nothing -- not failure
bytes = if numbits > 1 bytes = if numbits > 1
then Just <$> readish =<< headMaybe (drop 1 bits) then Just <$> readish =<< headMaybe (drop 1 bits)

View file

@ -81,7 +81,7 @@ readUnusedLog prefix = do
, return M.empty , return M.empty
) )
where where
parse line = case (readish sint, deserializeKey skey, parsePOSIXTime ts) of parse line = case (readish sint, deserializeKey skey, parsePOSIXTime (encodeBS ts)) of
(Just int, Just key, mtimestamp) -> Just (key, (int, mtimestamp)) (Just int, Just key, mtimestamp) -> Just (key, (int, mtimestamp))
_ -> Nothing _ -> Nothing
where where

View file

@ -39,7 +39,7 @@ readUpgradeLog = do
, return [] , return []
) )
where where
parse line = case (readish sint, parsePOSIXTime ts) of parse line = case (readish sint, parsePOSIXTime (encodeBS ts)) of
(Just v, Just t) -> Just (RepoVersion v, t) (Just v, Just t) -> Just (RepoVersion v, t)
_ -> Nothing _ -> Nothing
where where

View file

@ -185,7 +185,7 @@ readInodeCache s = case words s of
(inode:size:mtime:mtimedecimal:_) -> do (inode:size:mtime:mtimedecimal:_) -> do
i <- readish inode i <- readish inode
sz <- readish size sz <- readish size
t <- parsePOSIXTime $ mtime ++ '.' : mtimedecimal t <- parsePOSIXTime $ encodeBS $ mtime ++ '.' : mtimedecimal
return $ InodeCache $ InodeCachePrim i sz (MTimeHighRes t) return $ InodeCache $ InodeCachePrim i sz (MTimeHighRes t)
_ -> Nothing _ -> Nothing

View file

@ -19,7 +19,6 @@ import Data.Time
import Data.Ratio import Data.Ratio
import Control.Applicative import Control.Applicative
import qualified Data.ByteString as B import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import qualified Data.Attoparsec.ByteString as A import qualified Data.Attoparsec.ByteString as A
import Data.Attoparsec.ByteString.Char8 (char, decimal, signed, isDigit_w8) import Data.Attoparsec.ByteString.Char8 (char, decimal, signed, isDigit_w8)
@ -41,9 +40,9 @@ parserPOSIXTime = mkPOSIXTime
A.parseOnly (decimal <* A.endOfInput) b A.parseOnly (decimal <* A.endOfInput) b
return (d, len) return (d, len)
parsePOSIXTime :: String -> Maybe POSIXTime parsePOSIXTime :: B.ByteString -> Maybe POSIXTime
parsePOSIXTime s = eitherToMaybe $ parsePOSIXTime b = eitherToMaybe $
A.parseOnly (parserPOSIXTime <* A.endOfInput) (B8.pack s) A.parseOnly (parserPOSIXTime <* A.endOfInput) b
{- This implementation allows for higher precision in a POSIXTime than {- This implementation allows for higher precision in a POSIXTime than
- supported by the system's Double, and avoids the complications of - supported by the system's Double, and avoids the complications of

View file

@ -21,6 +21,10 @@ status.
readFile, writeFile, and appendFile on FilePaths. readFile, writeFile, and appendFile on FilePaths.
Note that the FilePath versions do newline translation on windows, Note that the FilePath versions do newline translation on windows,
which has to be handled when converting to the Utility.FileIO ones. which has to be handled when converting to the Utility.FileIO ones.
* System.Directory.OsPath is available with OsPath build flag, but
not yet used, and would eliminate a lot of fromRawFilePaths.
Make Utility.SystemDirectory import it when built with OsPath,
and the remaining 6 hours or work will explain itself..
[[!tag confirmed]] [[!tag confirmed]]