// CompactVolume compact a super block to another file. func (s *Store) CompactVolume(id int32) (err error) { var ( v, nv *volume.Volume bdir, idir string ) // try check volume if v = s.Volumes[id]; v != nil { if v.Compact { return errors.ErrVolumeInCompact } } else { return errors.ErrVolumeExist } // find a free volume if nv, err = s.freeVolume(id); err != nil { return } // no lock here, Compact is no side-effect if err = v.StartCompact(nv); err != nil { v.StopCompact(nil) return } s.vlock.Lock() if v = s.Volumes[id]; v != nil { if err = v.StopCompact(nv); err == nil { // WARN no need update volumes map, use same object, only update // zookeeper the local index cause the block and index file changed. if err = s.saveVolumeIndex(); err == nil { err = s.zk.SetVolume(v) } } } else { err = errors.ErrVolumeExist } s.vlock.Unlock() if err == nil { // nv now has old block/index nv.Close() nv.Destroy() bdir, idir = filepath.Dir(nv.Block.File), filepath.Dir(nv.Indexer.File) _, err = s.AddFreeVolume(1, bdir, idir) } return }