groundwork for parameterizing hash depth
This commit is contained in:
parent
037d86e046
commit
0fd5f257d0
11 changed files with 52 additions and 32 deletions
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
module Command.Find where
|
module Command.Find where
|
||||||
|
|
||||||
|
import Data.Default
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
|
@ -65,8 +66,8 @@ keyVars key =
|
||||||
, ("bytesize", size show)
|
, ("bytesize", size show)
|
||||||
, ("humansize", size $ roughSize storageUnits True)
|
, ("humansize", size $ roughSize storageUnits True)
|
||||||
, ("keyname", keyName key)
|
, ("keyname", keyName key)
|
||||||
, ("hashdirlower", hashDirLower key)
|
, ("hashdirlower", hashDirLower def key)
|
||||||
, ("hashdirmixed", hashDirMixed key)
|
, ("hashdirmixed", hashDirMixed def key)
|
||||||
, ("mtime", whenavail show $ keyMtime key)
|
, ("mtime", whenavail show $ keyMtime key)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
|
|
33
Locations.hs
33
Locations.hs
|
@ -60,6 +60,7 @@ module Locations (
|
||||||
gitAnnexAssistantDefaultDir,
|
gitAnnexAssistantDefaultDir,
|
||||||
isLinkToAnnex,
|
isLinkToAnnex,
|
||||||
annexHashes,
|
annexHashes,
|
||||||
|
HashLevels(..),
|
||||||
hashDirMixed,
|
hashDirMixed,
|
||||||
hashDirLower,
|
hashDirLower,
|
||||||
preSanitizeKeyName,
|
preSanitizeKeyName,
|
||||||
|
@ -71,6 +72,7 @@ import Data.Bits
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Data.Hash.MD5
|
import Data.Hash.MD5
|
||||||
import Data.Char
|
import Data.Char
|
||||||
|
import Data.Default
|
||||||
|
|
||||||
import Common
|
import Common
|
||||||
import Types
|
import Types
|
||||||
|
@ -105,7 +107,7 @@ objectDir = addTrailingPathSeparator $ annexDir </> "objects"
|
||||||
{- Annexed file's possible locations relative to the .git directory.
|
{- Annexed file's possible locations relative to the .git directory.
|
||||||
- There are two different possibilities, using different hashes. -}
|
- There are two different possibilities, using different hashes. -}
|
||||||
annexLocations :: Key -> [FilePath]
|
annexLocations :: Key -> [FilePath]
|
||||||
annexLocations key = map (annexLocation key) annexHashes
|
annexLocations key = map (annexLocation key) (annexHashes def)
|
||||||
annexLocation :: Key -> Hasher -> FilePath
|
annexLocation :: Key -> Hasher -> FilePath
|
||||||
annexLocation key hasher = objectDir </> keyPath key hasher
|
annexLocation key hasher = objectDir </> keyPath key hasher
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ gitAnnexLocation' key r config crippled
|
||||||
{- Non-bare repositories only use hashDirMixed, so
|
{- Non-bare repositories only use hashDirMixed, so
|
||||||
- don't need to do any work to check if the file is
|
- don't need to do any work to check if the file is
|
||||||
- present. -}
|
- present. -}
|
||||||
| otherwise = return $ inrepo $ annexLocation key hashDirMixed
|
| otherwise = return $ inrepo $ annexLocation key (hashDirMixed def)
|
||||||
where
|
where
|
||||||
inrepo d = Git.localGitDir r </> d
|
inrepo d = Git.localGitDir r </> d
|
||||||
check locs@(l:_) = fromMaybe l <$> firstM doesFileExist locs
|
check locs@(l:_) = fromMaybe l <$> firstM doesFileExist locs
|
||||||
|
@ -419,28 +421,35 @@ keyPath key hasher = hasher key </> f </> f
|
||||||
|
|
||||||
{- All possibile locations to store a key using different directory hashes. -}
|
{- All possibile locations to store a key using different directory hashes. -}
|
||||||
keyPaths :: Key -> [FilePath]
|
keyPaths :: Key -> [FilePath]
|
||||||
keyPaths key = map (keyPath key) annexHashes
|
keyPaths key = map (keyPath key) (annexHashes def)
|
||||||
|
|
||||||
{- Two different directory hashes may be used. The mixed case hash
|
{- Two different directory hashes may be used. The mixed case hash
|
||||||
- came first, and is fine, except for the problem of case-strict
|
- came first, and is fine, except for the problem of case-strict
|
||||||
- filesystems such as Linux VFAT (mounted with shortname=mixed),
|
- filesystems such as Linux VFAT (mounted with shortname=mixed),
|
||||||
- which do not allow using a directory "XX" when "xx" already exists.
|
- which do not allow using a directory "XX" when "xx" already exists.
|
||||||
- To support that, most repositories use the lower case hash for new data. -}
|
- To support that, most repositories use the lower case hash for new data. -}
|
||||||
|
annexHashes :: HashLevels -> [Hasher]
|
||||||
|
annexHashes n = [hashDirLower n, hashDirMixed n]
|
||||||
|
|
||||||
type Hasher = Key -> FilePath
|
type Hasher = Key -> FilePath
|
||||||
|
|
||||||
annexHashes :: [Hasher]
|
-- Number of hash levels to use. 2 is the default.
|
||||||
annexHashes = [hashDirLower, hashDirMixed]
|
newtype HashLevels = HashLevels Int
|
||||||
|
|
||||||
hashDirMixed :: Hasher
|
instance Default HashLevels where
|
||||||
hashDirMixed k = addTrailingPathSeparator $ take 2 dir </> drop 2 dir
|
def = HashLevels 2
|
||||||
|
|
||||||
|
hashDirs :: HashLevels -> Int -> String -> FilePath
|
||||||
|
hashDirs (HashLevels 1) sz s = addTrailingPathSeparator $ take sz s
|
||||||
|
hashDirs _ sz s = addTrailingPathSeparator $ take sz s </> drop sz s
|
||||||
|
|
||||||
|
hashDirMixed :: HashLevels -> Hasher
|
||||||
|
hashDirMixed n k = hashDirs n 2 $ take 4 $ display_32bits_as_dir =<< [a,b,c,d]
|
||||||
where
|
where
|
||||||
dir = take 4 $ display_32bits_as_dir =<< [a,b,c,d]
|
|
||||||
ABCD (a,b,c,d) = md5 $ md5FilePath $ key2file $ nonChunkKey k
|
ABCD (a,b,c,d) = md5 $ md5FilePath $ key2file $ nonChunkKey k
|
||||||
|
|
||||||
hashDirLower :: Hasher
|
hashDirLower :: HashLevels -> Hasher
|
||||||
hashDirLower k = addTrailingPathSeparator $ take 3 dir </> drop 3 dir
|
hashDirLower n k = hashDirs n 3 $ take 6 $ md5s $ md5FilePath $ key2file $ nonChunkKey k
|
||||||
where
|
|
||||||
dir = take 6 $ md5s $ md5FilePath $ key2file $ nonChunkKey k
|
|
||||||
|
|
||||||
{- modified version of display_32bits_as_hex from Data.Hash.MD5
|
{- modified version of display_32bits_as_hex from Data.Hash.MD5
|
||||||
- Copyright (C) 2001 Ian Lynagh
|
- Copyright (C) 2001 Ian Lynagh
|
||||||
|
|
16
Logs.hs
16
Logs.hs
|
@ -10,6 +10,8 @@ module Logs where
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
|
||||||
|
import Data.Default
|
||||||
|
|
||||||
{- There are several varieties of log file formats. -}
|
{- There are several varieties of log file formats. -}
|
||||||
data LogVariety
|
data LogVariety
|
||||||
= UUIDBasedLog
|
= UUIDBasedLog
|
||||||
|
@ -88,7 +90,7 @@ differenceLog = "difference.log"
|
||||||
|
|
||||||
{- The pathname of the location log file for a given key. -}
|
{- The pathname of the location log file for a given key. -}
|
||||||
locationLogFile :: Key -> String
|
locationLogFile :: Key -> String
|
||||||
locationLogFile key = hashDirLower key ++ keyFile key ++ ".log"
|
locationLogFile key = hashDirLower def key ++ keyFile key ++ ".log"
|
||||||
|
|
||||||
{- Converts a pathname into a key if it's a location log. -}
|
{- Converts a pathname into a key if it's a location log. -}
|
||||||
locationLogFileKey :: FilePath -> Maybe Key
|
locationLogFileKey :: FilePath -> Maybe Key
|
||||||
|
@ -102,13 +104,13 @@ locationLogFileKey path
|
||||||
|
|
||||||
{- The filename of the url log for a given key. -}
|
{- The filename of the url log for a given key. -}
|
||||||
urlLogFile :: Key -> FilePath
|
urlLogFile :: Key -> FilePath
|
||||||
urlLogFile key = hashDirLower key </> keyFile key ++ urlLogExt
|
urlLogFile key = hashDirLower def key </> keyFile key ++ urlLogExt
|
||||||
|
|
||||||
{- Old versions stored the urls elsewhere. -}
|
{- Old versions stored the urls elsewhere. -}
|
||||||
oldurlLogs :: Key -> [FilePath]
|
oldurlLogs :: Key -> [FilePath]
|
||||||
oldurlLogs key =
|
oldurlLogs key =
|
||||||
[ "remote/web" </> hashDirLower key </> key2file key ++ ".log"
|
[ "remote/web" </> hashDirLower def key </> key2file key ++ ".log"
|
||||||
, "remote/web" </> hashDirLower key </> keyFile key ++ ".log"
|
, "remote/web" </> hashDirLower def key </> keyFile key ++ ".log"
|
||||||
]
|
]
|
||||||
|
|
||||||
urlLogExt :: String
|
urlLogExt :: String
|
||||||
|
@ -131,7 +133,7 @@ isUrlLog file = urlLogExt `isSuffixOf` file
|
||||||
|
|
||||||
{- The filename of the remote state log for a given key. -}
|
{- The filename of the remote state log for a given key. -}
|
||||||
remoteStateLogFile :: Key -> FilePath
|
remoteStateLogFile :: Key -> FilePath
|
||||||
remoteStateLogFile key = hashDirLower key </> keyFile key ++ remoteStateLogExt
|
remoteStateLogFile key = hashDirLower def key </> keyFile key ++ remoteStateLogExt
|
||||||
|
|
||||||
remoteStateLogExt :: String
|
remoteStateLogExt :: String
|
||||||
remoteStateLogExt = ".log.rmt"
|
remoteStateLogExt = ".log.rmt"
|
||||||
|
@ -141,7 +143,7 @@ isRemoteStateLog path = remoteStateLogExt `isSuffixOf` path
|
||||||
|
|
||||||
{- The filename of the chunk log for a given key. -}
|
{- The filename of the chunk log for a given key. -}
|
||||||
chunkLogFile :: Key -> FilePath
|
chunkLogFile :: Key -> FilePath
|
||||||
chunkLogFile key = hashDirLower key </> keyFile key ++ chunkLogExt
|
chunkLogFile key = hashDirLower def key </> keyFile key ++ chunkLogExt
|
||||||
|
|
||||||
chunkLogFileKey :: FilePath -> Maybe Key
|
chunkLogFileKey :: FilePath -> Maybe Key
|
||||||
chunkLogFileKey path
|
chunkLogFileKey path
|
||||||
|
@ -160,7 +162,7 @@ isChunkLog path = chunkLogExt `isSuffixOf` path
|
||||||
|
|
||||||
{- The filename of the metadata log for a given key. -}
|
{- The filename of the metadata log for a given key. -}
|
||||||
metaDataLogFile :: Key -> FilePath
|
metaDataLogFile :: Key -> FilePath
|
||||||
metaDataLogFile key = hashDirLower key </> keyFile key ++ metaDataLogExt
|
metaDataLogFile key = hashDirLower def key </> keyFile key ++ metaDataLogExt
|
||||||
|
|
||||||
metaDataLogExt :: String
|
metaDataLogExt :: String
|
||||||
metaDataLogExt = ".log.met"
|
metaDataLogExt = ".log.met"
|
||||||
|
|
|
@ -15,6 +15,7 @@ module Remote.Directory (
|
||||||
|
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
import Data.Default
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Types.Remote
|
import Types.Remote
|
||||||
|
@ -107,7 +108,7 @@ getLocation d k = do
|
||||||
|
|
||||||
{- Directory where the file(s) for a key are stored. -}
|
{- Directory where the file(s) for a key are stored. -}
|
||||||
storeDir :: FilePath -> Key -> FilePath
|
storeDir :: FilePath -> Key -> FilePath
|
||||||
storeDir d k = addTrailingPathSeparator $ d </> hashDirLower k </> keyFile k
|
storeDir d k = addTrailingPathSeparator $ d </> hashDirLower def k </> keyFile k
|
||||||
|
|
||||||
{- Where we store temporary data for a key, in the directory, as it's being
|
{- Where we store temporary data for a key, in the directory, as it's being
|
||||||
- written. -}
|
- written. -}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import Creds
|
||||||
import Control.Concurrent.STM
|
import Control.Concurrent.STM
|
||||||
import System.Log.Logger (debugM)
|
import System.Log.Logger (debugM)
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
import Data.Default
|
||||||
|
|
||||||
remote :: RemoteType
|
remote :: RemoteType
|
||||||
remote = RemoteType {
|
remote = RemoteType {
|
||||||
|
@ -184,7 +185,7 @@ handleRequest' lck external req mp responsehandler
|
||||||
handleRemoteRequest (PROGRESS bytesprocessed) =
|
handleRemoteRequest (PROGRESS bytesprocessed) =
|
||||||
maybe noop (\a -> liftIO $ a bytesprocessed) mp
|
maybe noop (\a -> liftIO $ a bytesprocessed) mp
|
||||||
handleRemoteRequest (DIRHASH k) =
|
handleRemoteRequest (DIRHASH k) =
|
||||||
send $ VALUE $ hashDirMixed k
|
send $ VALUE $ hashDirMixed def k
|
||||||
handleRemoteRequest (SETCONFIG setting value) =
|
handleRemoteRequest (SETCONFIG setting value) =
|
||||||
liftIO $ atomically $ do
|
liftIO $ atomically $ do
|
||||||
let v = externalConfig external
|
let v = externalConfig external
|
||||||
|
|
|
@ -16,6 +16,7 @@ module Remote.GCrypt (
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import Control.Exception
|
import Control.Exception
|
||||||
|
import Data.Default
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Types.Remote
|
import Types.Remote
|
||||||
|
@ -361,7 +362,7 @@ checkKey r rsyncopts k
|
||||||
{- Annexed objects are hashed using lower-case directories for max
|
{- Annexed objects are hashed using lower-case directories for max
|
||||||
- portability. -}
|
- portability. -}
|
||||||
gCryptLocation :: Remote -> Key -> FilePath
|
gCryptLocation :: Remote -> Key -> FilePath
|
||||||
gCryptLocation r key = Git.repoLocation (repo r) </> objectDir </> keyPath key hashDirLower
|
gCryptLocation r key = Git.repoLocation (repo r) </> objectDir </> keyPath key (hashDirLower def)
|
||||||
|
|
||||||
data AccessMethod = AccessDirect | AccessShell
|
data AccessMethod = AccessDirect | AccessShell
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
module Remote.Hook (remote) where
|
module Remote.Hook (remote) where
|
||||||
|
|
||||||
import qualified Data.Map as M
|
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Types.Remote
|
import Types.Remote
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
@ -20,6 +18,9 @@ import Annex.UUID
|
||||||
import Remote.Helper.Special
|
import Remote.Helper.Special
|
||||||
import Utility.Env
|
import Utility.Env
|
||||||
|
|
||||||
|
import Data.Default
|
||||||
|
import qualified Data.Map as M
|
||||||
|
|
||||||
type Action = String
|
type Action = String
|
||||||
type HookName = String
|
type HookName = String
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ hookEnv action k f = Just <$> mergeenv (fileenv f ++ keyenv)
|
||||||
]
|
]
|
||||||
fileenv Nothing = []
|
fileenv Nothing = []
|
||||||
fileenv (Just file) = [envvar "FILE" file]
|
fileenv (Just file) = [envvar "FILE" file]
|
||||||
hashbits = map takeDirectory $ splitPath $ hashDirMixed k
|
hashbits = map takeDirectory $ splitPath $ hashDirMixed def k
|
||||||
|
|
||||||
lookupHook :: HookName -> Action -> Annex (Maybe String)
|
lookupHook :: HookName -> Action -> Annex (Maybe String)
|
||||||
lookupHook hookname action = do
|
lookupHook hookname action = do
|
||||||
|
|
|
@ -38,6 +38,7 @@ import Logs.Transfer
|
||||||
import Types.Creds
|
import Types.Creds
|
||||||
import Types.Key (isChunkKey)
|
import Types.Key (isChunkKey)
|
||||||
|
|
||||||
|
import Data.Default
|
||||||
import qualified Data.Map as M
|
import qualified Data.Map as M
|
||||||
|
|
||||||
remote :: RemoteType
|
remote :: RemoteType
|
||||||
|
@ -212,7 +213,7 @@ remove o k = do
|
||||||
- content could be. Note that the parent directories have
|
- content could be. Note that the parent directories have
|
||||||
- to also be explicitly included, due to how rsync
|
- to also be explicitly included, due to how rsync
|
||||||
- traverses directories. -}
|
- traverses directories. -}
|
||||||
includes = concatMap use annexHashes
|
includes = concatMap use (annexHashes def)
|
||||||
use h = let dir = h k in
|
use h = let dir = h k in
|
||||||
[ parentDir dir
|
[ parentDir dir
|
||||||
, dir
|
, dir
|
||||||
|
|
|
@ -14,6 +14,7 @@ import Locations
|
||||||
import Utility.Rsync
|
import Utility.Rsync
|
||||||
import Utility.SafeCommand
|
import Utility.SafeCommand
|
||||||
|
|
||||||
|
import Data.Default
|
||||||
import System.FilePath.Posix
|
import System.FilePath.Posix
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
import Data.String.Utils
|
import Data.String.Utils
|
||||||
|
@ -35,7 +36,7 @@ rsyncEscape o u
|
||||||
| otherwise = u
|
| otherwise = u
|
||||||
|
|
||||||
rsyncUrls :: RsyncOpts -> Key -> [RsyncUrl]
|
rsyncUrls :: RsyncOpts -> Key -> [RsyncUrl]
|
||||||
rsyncUrls o k = map use annexHashes
|
rsyncUrls o k = map use (annexHashes def)
|
||||||
where
|
where
|
||||||
use h = rsyncUrl o </> hash h </> rsyncEscape o (f </> f)
|
use h = rsyncUrl o </> hash h </> rsyncEscape o (f </> f)
|
||||||
f = keyFile k
|
f = keyFile k
|
||||||
|
|
|
@ -17,6 +17,7 @@ import Utility.Url (URLString)
|
||||||
import System.FilePath.Posix -- for manipulating url paths
|
import System.FilePath.Posix -- for manipulating url paths
|
||||||
import Network.Protocol.HTTP.DAV (inDAVLocation, DAVT)
|
import Network.Protocol.HTTP.DAV (inDAVLocation, DAVT)
|
||||||
import Control.Monad.IO.Class (MonadIO)
|
import Control.Monad.IO.Class (MonadIO)
|
||||||
|
import Data.Default
|
||||||
#ifdef mingw32_HOST_OS
|
#ifdef mingw32_HOST_OS
|
||||||
import Data.String.Utils
|
import Data.String.Utils
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,9 +34,9 @@ keyDir :: Key -> DavLocation
|
||||||
keyDir k = addTrailingPathSeparator $ hashdir </> keyFile k
|
keyDir k = addTrailingPathSeparator $ hashdir </> keyFile k
|
||||||
where
|
where
|
||||||
#ifndef mingw32_HOST_OS
|
#ifndef mingw32_HOST_OS
|
||||||
hashdir = hashDirLower k
|
hashdir = hashDirLower def k
|
||||||
#else
|
#else
|
||||||
hashdir = replace "\\" "/" (hashDirLower k)
|
hashdir = replace "\\" "/" (hashDirLower def k)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
keyLocation :: Key -> DavLocation
|
keyLocation :: Key -> DavLocation
|
||||||
|
|
|
@ -9,6 +9,7 @@ module Upgrade.V1 where
|
||||||
|
|
||||||
import System.Posix.Types
|
import System.Posix.Types
|
||||||
import Data.Char
|
import Data.Char
|
||||||
|
import Data.Default
|
||||||
|
|
||||||
import Common.Annex
|
import Common.Annex
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
@ -228,7 +229,7 @@ logFile1 :: Git.Repo -> Key -> String
|
||||||
logFile1 repo key = Upgrade.V2.gitStateDir repo ++ keyFile1 key ++ ".log"
|
logFile1 repo key = Upgrade.V2.gitStateDir repo ++ keyFile1 key ++ ".log"
|
||||||
|
|
||||||
logFile2 :: Key -> Git.Repo -> String
|
logFile2 :: Key -> Git.Repo -> String
|
||||||
logFile2 = logFile' hashDirLower
|
logFile2 = logFile' (hashDirLower def)
|
||||||
|
|
||||||
logFile' :: (Key -> FilePath) -> Key -> Git.Repo -> String
|
logFile' :: (Key -> FilePath) -> Key -> Git.Repo -> String
|
||||||
logFile' hasher key repo =
|
logFile' hasher key repo =
|
||||||
|
|
Loading…
Reference in a new issue