horrible impementation of isInodeKnown
The only good thing about it is it does not require a major version bump to improve the database. That will need to happen at some point though. Potentially very very slow in a large repository. Ugly use of raw sql.
This commit is contained in:
parent
eebf080b33
commit
94efc400e9
4 changed files with 65 additions and 2 deletions
|
@ -1,6 +1,6 @@
|
||||||
{- Sqlite database of information about Keys
|
{- Sqlite database of information about Keys
|
||||||
-
|
-
|
||||||
- Copyright 2015-2018 Joey Hess <id@joeyh.name>
|
- Copyright 2015-2019 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -19,6 +19,7 @@ module Database.Keys (
|
||||||
addInodeCaches,
|
addInodeCaches,
|
||||||
getInodeCaches,
|
getInodeCaches,
|
||||||
removeInodeCaches,
|
removeInodeCaches,
|
||||||
|
isInodeKnown,
|
||||||
runWriter,
|
runWriter,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
@ -187,6 +188,9 @@ getInodeCaches = runReaderIO . SQL.getInodeCaches . toIKey
|
||||||
removeInodeCaches :: Key -> Annex ()
|
removeInodeCaches :: Key -> Annex ()
|
||||||
removeInodeCaches = runWriterIO . SQL.removeInodeCaches . toIKey
|
removeInodeCaches = runWriterIO . SQL.removeInodeCaches . toIKey
|
||||||
|
|
||||||
|
isInodeKnown :: InodeCache -> SentinalStatus -> Annex Bool
|
||||||
|
isInodeKnown i s = or <$> runReaderIO ((:[]) <$$> SQL.isInodeKnown i s)
|
||||||
|
|
||||||
{- Looks at staged changes to find when unlocked files are copied/moved,
|
{- Looks at staged changes to find when unlocked files are copied/moved,
|
||||||
- and updates associated files in the keys database.
|
- and updates associated files in the keys database.
|
||||||
-
|
-
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- Sqlite database of information about Keys
|
{- Sqlite database of information about Keys
|
||||||
-
|
-
|
||||||
- Copyright 2015-2016 Joey Hess <id@joeyh.name>
|
- Copyright 2015-2019 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -23,6 +23,9 @@ import Database.Persist.Sql
|
||||||
import Database.Persist.TH
|
import Database.Persist.TH
|
||||||
import Data.Time.Clock
|
import Data.Time.Clock
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Data.Maybe
|
||||||
|
import qualified Data.Text as T
|
||||||
|
import qualified Data.Conduit.List as CL
|
||||||
|
|
||||||
share [mkPersist sqlSettings, mkMigrate "migrateKeysDb"] [persistLowerCase|
|
share [mkPersist sqlSettings, mkMigrate "migrateKeysDb"] [persistLowerCase|
|
||||||
Associated
|
Associated
|
||||||
|
@ -116,3 +119,31 @@ getInodeCaches ik = readDb $ do
|
||||||
removeInodeCaches :: IKey -> WriteHandle -> IO ()
|
removeInodeCaches :: IKey -> WriteHandle -> IO ()
|
||||||
removeInodeCaches ik = queueDb $
|
removeInodeCaches ik = queueDb $
|
||||||
deleteWhere [ContentKey ==. ik]
|
deleteWhere [ContentKey ==. ik]
|
||||||
|
|
||||||
|
{- Check if the inode is known to be used for an annexed file.
|
||||||
|
-
|
||||||
|
- This is currently slow due to the lack of indexes.
|
||||||
|
-}
|
||||||
|
isInodeKnown :: InodeCache -> SentinalStatus -> ReadHandle -> IO Bool
|
||||||
|
isInodeKnown i s = readDb query
|
||||||
|
where
|
||||||
|
query
|
||||||
|
| sentinalInodesChanged s =
|
||||||
|
withRawQuery likesql [] $ isJust <$> CL.head
|
||||||
|
| otherwise =
|
||||||
|
isJust <$> selectFirst [ContentCache ==. si] []
|
||||||
|
|
||||||
|
si = toSInodeCache i
|
||||||
|
|
||||||
|
likesql = T.concat
|
||||||
|
[ "SELECT key FROM content WHERE "
|
||||||
|
, T.unwords (map mklike (likeInodeCacheWeak i))
|
||||||
|
, " LIMIT 1"
|
||||||
|
]
|
||||||
|
|
||||||
|
mklike p = T.concat
|
||||||
|
[ "cache LIKE "
|
||||||
|
, "'I \"" -- SInodeCache serializes as I "..."
|
||||||
|
, T.pack p
|
||||||
|
, "\"'"
|
||||||
|
]
|
||||||
|
|
|
@ -23,6 +23,7 @@ module Utility.InodeCache (
|
||||||
showInodeCache,
|
showInodeCache,
|
||||||
genInodeCache,
|
genInodeCache,
|
||||||
toInodeCache,
|
toInodeCache,
|
||||||
|
likeInodeCacheWeak,
|
||||||
|
|
||||||
InodeCacheKey,
|
InodeCacheKey,
|
||||||
inodeCacheToKey,
|
inodeCacheToKey,
|
||||||
|
@ -149,6 +150,22 @@ showInodeCache (InodeCache (InodeCachePrim inode size (MTimeLowRes mtime))) =
|
||||||
, show mtime
|
, show mtime
|
||||||
]
|
]
|
||||||
|
|
||||||
|
-- Generates patterns that can be used in a SQL LIKE query to match
|
||||||
|
-- serialized inode caches that are weakly the same as the provided
|
||||||
|
-- InodeCache.
|
||||||
|
--
|
||||||
|
-- Like compareWeak, the size has to match, while the mtime can differ
|
||||||
|
-- by anything less than 2 seconds.
|
||||||
|
likeInodeCacheWeak :: InodeCache -> [String]
|
||||||
|
likeInodeCacheWeak (InodeCache (InodeCachePrim _ size mtime)) =
|
||||||
|
lowresl ++ highresl
|
||||||
|
where
|
||||||
|
lowresl = map mkpat [t, t+1, t-1]
|
||||||
|
highresl = map (++ " %") lowresl
|
||||||
|
t = lowResTime mtime
|
||||||
|
mkpat t' = "% " ++ ssz ++ " " ++ show t'
|
||||||
|
ssz = show size
|
||||||
|
|
||||||
readInodeCache :: String -> Maybe InodeCache
|
readInodeCache :: String -> Maybe InodeCache
|
||||||
readInodeCache s = case words s of
|
readInodeCache s = case words s of
|
||||||
(inode:size:mtime:[]) -> do
|
(inode:size:mtime:[]) -> do
|
||||||
|
|
|
@ -2,6 +2,17 @@ Collection of non-ideal things about git-annex's use of sqlite databases.
|
||||||
Would be good to improve these sometime, but it would need a migration
|
Would be good to improve these sometime, but it would need a migration
|
||||||
process.
|
process.
|
||||||
|
|
||||||
|
* Database.Keys.SQL.isInodeKnown seems likely to get very slow
|
||||||
|
when there are a lot of unlocked annexed files. It needs
|
||||||
|
an index in the database, eg "InodeIndex cache"
|
||||||
|
|
||||||
|
It also has to do some really ugly SQL LIKE queries. Probably an index
|
||||||
|
would not speed them up. They're only needed when git-annex detects
|
||||||
|
inodes are not stable, eg on fat or probably windows. A better database
|
||||||
|
schema should be able to eliminate the need for those LIKE queries.
|
||||||
|
Eg, store the size and allowable mtimes in a separate table that is
|
||||||
|
queried when necessary.
|
||||||
|
|
||||||
* Database.Export.getExportedKey would be faster if there was an index
|
* Database.Export.getExportedKey would be faster if there was an index
|
||||||
in the database, eg "ExportedIndex file key". This only affects
|
in the database, eg "ExportedIndex file key". This only affects
|
||||||
the speed of `git annex export`, which is probably swamped by the actual
|
the speed of `git annex export`, which is probably swamped by the actual
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue