repl = *coll.ReplicationDesired
}
debugf("%v: %d block x%d", coll.UUID, len(blkids), repl)
- bal.BlockStateMap.IncreaseDesired(coll.StorageClassesDesired, repl, blkids)
+ // Pass pdh to IncreaseDesired only if LostBlocksFile is being
+ // written -- otherwise it's just a waste of memory.
+ pdh := ""
+ if bal.LostBlocksFile != "" {
+ pdh = coll.PortableDataHash
+ }
+ bal.BlockStateMap.IncreaseDesired(pdh, coll.StorageClassesDesired, repl, blkids)
return nil
}
s.lost.replicas -= surplus
s.lost.blocks++
s.lost.bytes += bytes * int64(-surplus)
- fmt.Fprintf(bal.lostBlocks, "%s\n", strings.SplitN(string(result.blkid), "+", 2)[0])
+ fmt.Fprintf(bal.lostBlocks, "%s", strings.SplitN(string(result.blkid), "+", 2)[0])
+ for pdh := range result.blk.Refs {
+ fmt.Fprintf(bal.lostBlocks, " %s", pdh)
+ }
+ fmt.Fprint(bal.lostBlocks, "\n")
case surplus < 0:
s.underrep.replicas -= surplus
s.underrep.blocks++
c.Check(err, check.IsNil)
lost, err := ioutil.ReadFile(lostf.Name())
c.Assert(err, check.IsNil)
- c.Check(string(lost), check.Equals, "37b51d194a7513e45b56f6524f2d51f2\n")
+ c.Check(string(lost), check.Equals, "37b51d194a7513e45b56f6524f2d51f2 fa7aeb5140e2848d39b416daeef4ffc5+45\n")
}
func (s *runSuite) TestDryRun(c *check.C) {
// replicas actually stored (according to the keepstore indexes we
// know about).
type BlockState struct {
+ Refs map[string]bool // pdh => true (only tracked when len(Replicas)==0)
RefCount int
Replicas []Replica
Desired map[string]int
func (bs *BlockState) addReplica(r Replica) {
bs.Replicas = append(bs.Replicas, r)
+ // Free up memory wasted by tracking PDHs that will never be
+ // reported (see comment in increaseDesired)
+ bs.Refs = nil
}
-func (bs *BlockState) increaseDesired(classes []string, n int) {
+func (bs *BlockState) increaseDesired(pdh string, classes []string, n int) {
+ if pdh != "" && len(bs.Replicas) == 0 {
+ // Note we only track PDHs if there's a possibility
+ // that we will report the list of referring PDHs,
+ // i.e., if we haven't yet seen a replica.
+ if bs.Refs == nil {
+ bs.Refs = map[string]bool{}
+ }
+ bs.Refs[pdh] = true
+ }
bs.RefCount++
if len(classes) == 0 {
classes = defaultClasses
// IncreaseDesired updates the map to indicate the desired replication
// for the given blocks in the given storage class is at least n.
-func (bsm *BlockStateMap) IncreaseDesired(classes []string, n int, blocks []arvados.SizedDigest) {
+//
+// If pdh is non-empty, it will be tracked and reported in the "lost
+// blocks" report.
+func (bsm *BlockStateMap) IncreaseDesired(pdh string, classes []string, n int, blocks []arvados.SizedDigest) {
bsm.mutex.Lock()
defer bsm.mutex.Unlock()
for _, blkid := range blocks {
- bsm.get(blkid).increaseDesired(classes, n)
+ bsm.get(blkid).increaseDesired(pdh, classes, n)
}
}