From 5bca78b81313920358cc77796879dc8c46d5778e Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 25 Jan 2025 11:53:47 -0400 Subject: [PATCH] OsPath conversion Decent win in exportDirectories, since it operates on ShortByteString end to end now without needing conversion. That made it worth implementing an OsPath specific code path there. And ExportLocation already being a ShortByteString is an good example of why it's a good thing that OsPath uses that! Sponsored-by: k0ld on Patreon --- Types/Export.hs | 50 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/Types/Export.hs b/Types/Export.hs index 1116b67b8c..735a235285 100644 --- a/Types/Export.hs +++ b/Types/Export.hs @@ -1,11 +1,12 @@ {- git-annex export types - - - Copyright 2017-2021 Joey Hess + - Copyright 2017-2025 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE CPP #-} module Types.Export ( ExportLocation, @@ -19,48 +20,63 @@ module Types.Export ( import Git.FilePath import Utility.Split -import Utility.FileSystemEncoding +import Utility.OsPath -import qualified Data.ByteString.Short as S -import qualified System.FilePath.Posix as Posix import GHC.Generics import Control.DeepSeq +#ifdef WITH_OSPATH +import qualified System.OsPath.Posix as Posix +import System.OsString.Internal.Types +#else +import qualified System.FilePath.Posix as Posix +import Utility.FileSystemEncoding +#endif -- A location such as a path on a remote, that a key can be exported to. -- The path is relative to the top of the remote, and uses unix-style -- path separators. -- --- This uses a ShortByteString to avoid problems with ByteString getting --- PINNED in memory which caused memory fragmentation and excessive memory --- use. -newtype ExportLocation = ExportLocation S.ShortByteString +-- This must be a ShortByteString (which OsPath is) in order to to avoid +-- problems with ByteString getting PINNED in memory which caused memory +-- fragmentation and excessive memory use. +newtype ExportLocation = ExportLocation OsPath deriving (Show, Eq, Generic, Ord) instance NFData ExportLocation -mkExportLocation :: RawFilePath -> ExportLocation -mkExportLocation = ExportLocation . S.toShort . toInternalGitPath +mkExportLocation :: OsPath -> ExportLocation +mkExportLocation = ExportLocation . toInternalGitPath -fromExportLocation :: ExportLocation -> RawFilePath -fromExportLocation (ExportLocation f) = S.fromShort f +fromExportLocation :: ExportLocation -> OsPath +fromExportLocation (ExportLocation f) = f -newtype ExportDirectory = ExportDirectory RawFilePath +newtype ExportDirectory = ExportDirectory OsPath deriving (Show, Eq) -mkExportDirectory :: RawFilePath -> ExportDirectory +mkExportDirectory :: OsPath -> ExportDirectory mkExportDirectory = ExportDirectory . toInternalGitPath -fromExportDirectory :: ExportDirectory -> RawFilePath +fromExportDirectory :: ExportDirectory -> OsPath fromExportDirectory (ExportDirectory f) = f -- | All subdirectories down to the ExportLocation, with the deepest ones -- last. Does not include the top of the export. exportDirectories :: ExportLocation -> [ExportDirectory] exportDirectories (ExportLocation f) = - map (ExportDirectory . encodeBS . Posix.joinPath . reverse) (subs [] dirs) + map (ExportDirectory . fromposixpath . Posix.joinPath . reverse) + (subs [] dirs) where subs _ [] = [] subs ps (d:ds) = (d:ps) : subs (d:ps) ds +#ifdef WITH_OSPATH dirs = map Posix.dropTrailingPathSeparator $ - dropFromEnd 1 $ Posix.splitPath $ decodeBS $ S.fromShort f + dropFromEnd 1 $ Posix.splitPath $ PosixString $ fromOsPath f + + fromposixpath = toOsPath . getPosixString +#else + dirs = map Posix.dropTrailingPathSeparator $ + dropFromEnd 1 $ Posix.splitPath $ fromOsPath f + + fromposixpath = encodeBS +#endif