split cost out into its own module
Added a function to insert a new cost into a list, which could be used to asjust costs after a drag and drop.
This commit is contained in:
parent
672fb29b06
commit
19c0a0d5b1
18 changed files with 103 additions and 37 deletions
|
@ -21,12 +21,13 @@ import Logs.UUID
|
|||
import Logs.Remote
|
||||
import Git.Remote
|
||||
import Config
|
||||
import Config.Cost
|
||||
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Map as M
|
||||
|
||||
{- Sets up and begins syncing with a new ssh or rsync remote. -}
|
||||
makeSshRemote :: Bool -> SshData -> Maybe Int -> Assistant Remote
|
||||
makeSshRemote :: Bool -> SshData -> Maybe Cost -> Assistant Remote
|
||||
makeSshRemote forcersync sshdata mcost = do
|
||||
r <- liftAnnex $
|
||||
addRemote $ maker (sshRepoName sshdata) sshurl
|
||||
|
|
|
@ -13,6 +13,7 @@ import Assistant.Pairing
|
|||
import Assistant.Pairing.Network
|
||||
import Assistant.MakeRemote
|
||||
import Config
|
||||
import Config.Cost
|
||||
|
||||
import Network.Socket
|
||||
import qualified Data.Text as T
|
||||
|
|
|
@ -13,7 +13,7 @@ import Control.Concurrent.STM
|
|||
import qualified Data.Map as M
|
||||
|
||||
data ScanInfo = ScanInfo
|
||||
{ scanPriority :: Int
|
||||
{ scanPriority :: Float
|
||||
, fullScan :: Bool
|
||||
}
|
||||
|
||||
|
|
32
Config.hs
32
Config.hs
|
@ -13,6 +13,7 @@ import qualified Git.Config
|
|||
import qualified Git.Command
|
||||
import qualified Annex
|
||||
import qualified Types.Remote as Remote
|
||||
import Config.Cost
|
||||
|
||||
type UnqualifiedConfigKey = String
|
||||
data ConfigKey = ConfigKey String
|
||||
|
@ -44,43 +45,16 @@ annexConfig key = ConfigKey $ "annex." ++ key
|
|||
{- Calculates cost for a remote. Either the specific default, or as configured
|
||||
- by remote.<name>.annex-cost, or if remote.<name>.annex-cost-command
|
||||
- is set and prints a number, that is used. -}
|
||||
remoteCost :: RemoteGitConfig -> Int -> Annex Int
|
||||
remoteCost :: RemoteGitConfig -> Cost -> Annex Cost
|
||||
remoteCost c def = case remoteAnnexCostCommand c of
|
||||
Just cmd | not (null cmd) -> liftIO $
|
||||
(fromMaybe def . readish) <$>
|
||||
readProcess "sh" ["-c", cmd]
|
||||
_ -> return $ fromMaybe def $ remoteAnnexCost c
|
||||
|
||||
setRemoteCost :: Remote -> Int -> Annex ()
|
||||
setRemoteCost :: Remote -> Cost -> Annex ()
|
||||
setRemoteCost r c = setConfig (remoteConfig (Remote.repo r) "cost") (show c)
|
||||
|
||||
cheapRemoteCost :: Int
|
||||
cheapRemoteCost = 100
|
||||
semiCheapRemoteCost :: Int
|
||||
semiCheapRemoteCost = 110
|
||||
semiExpensiveRemoteCost :: Int
|
||||
semiExpensiveRemoteCost = 175
|
||||
expensiveRemoteCost :: Int
|
||||
expensiveRemoteCost = 200
|
||||
veryExpensiveRemoteCost :: Int
|
||||
veryExpensiveRemoteCost = 1000
|
||||
|
||||
{- Adjusts a remote's cost to reflect it being encrypted. -}
|
||||
encryptedRemoteCostAdj :: Int
|
||||
encryptedRemoteCostAdj = 50
|
||||
|
||||
{- Make sure the remote cost numbers work out. -}
|
||||
prop_cost_sane :: Bool
|
||||
prop_cost_sane = False `notElem`
|
||||
[ expensiveRemoteCost > 0
|
||||
, cheapRemoteCost < semiCheapRemoteCost
|
||||
, semiCheapRemoteCost < semiExpensiveRemoteCost
|
||||
, semiExpensiveRemoteCost < expensiveRemoteCost
|
||||
, cheapRemoteCost + encryptedRemoteCostAdj > semiCheapRemoteCost
|
||||
, cheapRemoteCost + encryptedRemoteCostAdj < semiExpensiveRemoteCost
|
||||
, semiCheapRemoteCost + encryptedRemoteCostAdj < expensiveRemoteCost
|
||||
]
|
||||
|
||||
getNumCopies :: Maybe Int -> Annex Int
|
||||
getNumCopies (Just v) = return v
|
||||
getNumCopies Nothing = annexNumCopies <$> Annex.getGitConfig
|
||||
|
|
79
Config/Cost.hs
Normal file
79
Config/Cost.hs
Normal file
|
@ -0,0 +1,79 @@
|
|||
{- Remote costs.
|
||||
-
|
||||
- Copyright 2011-2013 Joey Hess <joey@kitenet.net>
|
||||
-
|
||||
- Licensed under the GNU GPL version 3 or higher.
|
||||
-}
|
||||
|
||||
module Config.Cost where
|
||||
|
||||
{- We use a float for a cost to ensure that there is a cost in
|
||||
- between any two other costs. -}
|
||||
type Cost = Float
|
||||
|
||||
{- Some predefined default costs.
|
||||
- Users setting costs in config files can be aware of these,
|
||||
- and pick values relative to them. So don't change. -}
|
||||
cheapRemoteCost :: Cost
|
||||
cheapRemoteCost = 100
|
||||
nearlyCheapRemoteCost :: Cost
|
||||
nearlyCheapRemoteCost = 110
|
||||
semiExpensiveRemoteCost :: Cost
|
||||
semiExpensiveRemoteCost = 175
|
||||
expensiveRemoteCost :: Cost
|
||||
expensiveRemoteCost = 200
|
||||
veryExpensiveRemoteCost :: Cost
|
||||
veryExpensiveRemoteCost = 1000
|
||||
|
||||
{- Adjusts a remote's cost to reflect it being encrypted. -}
|
||||
encryptedRemoteCostAdj :: Cost
|
||||
encryptedRemoteCostAdj = 50
|
||||
|
||||
{- Given an ordered list of costs, and the position of one of the items
|
||||
- the list, inserts a new cost into the list, in between the item
|
||||
- and the item after it.
|
||||
-
|
||||
- If both items have the same cost, one of them will have its cost
|
||||
- adjusted to make room. The costs of other items in the list are left
|
||||
- unchanged.
|
||||
-
|
||||
- To insert the new cost before any other in the list, specify a negative
|
||||
- position. To insert the new cost at the end of the list, specify a
|
||||
- position longer than the list.
|
||||
-}
|
||||
insertCostAfter :: [Cost] -> Int -> [Cost]
|
||||
insertCostAfter [] _ = error "insertCostAfter: empty list"
|
||||
insertCostAfter l pos
|
||||
| pos < 0 = costBetween 0 (l !! 0) : l
|
||||
| nextpos > maxpos = l ++ [1 + l !! maxpos]
|
||||
| item == nextitem =
|
||||
let (_dup:new:l') = insertCostAfter lastsegment 0
|
||||
in firstsegment ++ [costBetween item new, new] ++ l'
|
||||
| otherwise =
|
||||
firstsegment ++ [costBetween item nextitem ] ++ lastsegment
|
||||
where
|
||||
nextpos = pos + 1
|
||||
maxpos = length l - 1
|
||||
|
||||
item = l !! pos
|
||||
nextitem = l !! nextpos
|
||||
|
||||
(firstsegment, lastsegment) = splitAt (pos + 1) l
|
||||
|
||||
costBetween :: Cost -> Cost -> Cost
|
||||
costBetween x y
|
||||
| x == y = x
|
||||
| x > y = y + (x - y) / 2
|
||||
| otherwise = costBetween y x
|
||||
|
||||
{- Make sure the remote cost numbers work out. -}
|
||||
prop_cost_sane :: Bool
|
||||
prop_cost_sane = False `notElem`
|
||||
[ expensiveRemoteCost > 0
|
||||
, cheapRemoteCost < nearlyCheapRemoteCost
|
||||
, nearlyCheapRemoteCost < semiExpensiveRemoteCost
|
||||
, semiExpensiveRemoteCost < expensiveRemoteCost
|
||||
, cheapRemoteCost + encryptedRemoteCostAdj > nearlyCheapRemoteCost
|
||||
, nearlyCheapRemoteCost + encryptedRemoteCostAdj < semiExpensiveRemoteCost
|
||||
, nearlyCheapRemoteCost + encryptedRemoteCostAdj < expensiveRemoteCost
|
||||
]
|
|
@ -20,6 +20,7 @@ import qualified Git.Config
|
|||
import qualified Git.Construct
|
||||
import qualified Git.Ref
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Remote.Helper.Ssh
|
||||
import Remote.Helper.Special
|
||||
import Remote.Helper.Encryptable
|
||||
|
@ -44,7 +45,7 @@ gen r u c gc = do
|
|||
bupr <- liftIO $ bup2GitRemote buprepo
|
||||
cst <- remoteCost gc $
|
||||
if bupLocal buprepo
|
||||
then semiCheapRemoteCost
|
||||
then nearlyCheapRemoteCost
|
||||
else expensiveRemoteCost
|
||||
(u', bupr') <- getBupUUID bupr u
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import Data.Int
|
|||
import Common.Annex
|
||||
import Types.Remote
|
||||
import qualified Git
|
||||
import Config.Cost
|
||||
import Config
|
||||
import Utility.FileMode
|
||||
import Remote.Helper.Special
|
||||
|
|
|
@ -35,6 +35,7 @@ import qualified Annex.Branch
|
|||
import qualified Utility.Url as Url
|
||||
import Utility.TempFile
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Init
|
||||
import Types.Key
|
||||
import qualified Fields
|
||||
|
|
|
@ -16,6 +16,7 @@ import Types.Remote
|
|||
import Types.Key
|
||||
import qualified Git
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Remote.Helper.Special
|
||||
import Remote.Helper.Encryptable
|
||||
import qualified Remote.Helper.AWS as AWS
|
||||
|
|
|
@ -13,7 +13,7 @@ import Common.Annex
|
|||
import Types.Remote
|
||||
import Crypto
|
||||
import qualified Annex
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Utility.Base64
|
||||
|
||||
{- Encryption setup for a remote. The user must specify whether to use
|
||||
|
|
|
@ -16,6 +16,7 @@ import Types.Remote
|
|||
import Types.Key
|
||||
import qualified Git
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Annex.Content
|
||||
import Remote.Helper.Special
|
||||
import Remote.Helper.Encryptable
|
||||
|
|
|
@ -15,6 +15,7 @@ import Common.Annex
|
|||
import Types.Remote
|
||||
import qualified Git
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Annex.Content
|
||||
import Remote.Helper.Special
|
||||
import Remote.Helper.Encryptable
|
||||
|
|
|
@ -21,6 +21,7 @@ import Types.Remote
|
|||
import Types.Key
|
||||
import qualified Git
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Remote.Helper.Special
|
||||
import Remote.Helper.Encryptable
|
||||
import qualified Remote.Helper.AWS as AWS
|
||||
|
|
|
@ -13,6 +13,7 @@ import qualified Git
|
|||
import qualified Git.Construct
|
||||
import Annex.Content
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Logs.Web
|
||||
import qualified Utility.Url as Url
|
||||
import Types.Key
|
||||
|
|
|
@ -24,6 +24,7 @@ import Common.Annex
|
|||
import Types.Remote
|
||||
import qualified Git
|
||||
import Config
|
||||
import Config.Cost
|
||||
import Remote.Helper.Special
|
||||
import Remote.Helper.Encryptable
|
||||
import Remote.Helper.Chunked
|
||||
|
|
4
Test.hs
4
Test.hs
|
@ -42,7 +42,7 @@ import qualified Logs.Presence
|
|||
import qualified Remote
|
||||
import qualified Types.Key
|
||||
import qualified Types.Messages
|
||||
import qualified Config
|
||||
import qualified Config.Cost
|
||||
import qualified Crypto
|
||||
import qualified Utility.Path
|
||||
import qualified Utility.FileMode
|
||||
|
@ -102,7 +102,7 @@ quickcheck =
|
|||
, check "prop_parentDir_basics" Utility.Path.prop_parentDir_basics
|
||||
, check "prop_relPathDirToFile_basics" Utility.Path.prop_relPathDirToFile_basics
|
||||
, check "prop_relPathDirToFile_regressionTest" Utility.Path.prop_relPathDirToFile_regressionTest
|
||||
, check "prop_cost_sane" Config.prop_cost_sane
|
||||
, check "prop_cost_sane" Config.Cost.prop_cost_sane
|
||||
, check "prop_hmacWithCipher_sane" Crypto.prop_hmacWithCipher_sane
|
||||
, check "prop_TimeStamp_sane" Logs.UUIDBased.prop_TimeStamp_sane
|
||||
, check "prop_addLog_sane" Logs.UUIDBased.prop_addLog_sane
|
||||
|
|
|
@ -16,6 +16,7 @@ import Common
|
|||
import qualified Git
|
||||
import qualified Git.Config
|
||||
import Utility.DataUnits
|
||||
import Config.Cost
|
||||
|
||||
{- Main git-annex settings. Each setting corresponds to a git-config key
|
||||
- such as annex.foo -}
|
||||
|
@ -77,7 +78,7 @@ extractGitConfig r = GitConfig
|
|||
- key such as <remote>.annex-foo, or if that is not set, a default from
|
||||
- annex.foo -}
|
||||
data RemoteGitConfig = RemoteGitConfig
|
||||
{ remoteAnnexCost :: Maybe Int
|
||||
{ remoteAnnexCost :: Maybe Cost
|
||||
, remoteAnnexCostCommand :: Maybe String
|
||||
, remoteAnnexIgnore :: Bool
|
||||
, remoteAnnexSync :: Bool
|
||||
|
|
|
@ -17,6 +17,7 @@ import Types.Key
|
|||
import Types.UUID
|
||||
import Types.Meters
|
||||
import Types.GitConfig
|
||||
import Config.Cost
|
||||
|
||||
type RemoteConfigKey = String
|
||||
type RemoteConfig = M.Map RemoteConfigKey String
|
||||
|
@ -46,7 +47,7 @@ data RemoteA a = Remote {
|
|||
-- each Remote has a human visible name
|
||||
name :: String,
|
||||
-- Remotes have a use cost; higher is more expensive
|
||||
cost :: Int,
|
||||
cost :: Cost,
|
||||
-- Transfers a key to the remote.
|
||||
storeKey :: Key -> AssociatedFile -> MeterUpdate -> a Bool,
|
||||
-- retrieves a key's contents to a file
|
||||
|
|
Loading…
Reference in a new issue