@@ -34,6 +34,8 @@ type layerStore struct {
3434
3535 mounts map [string ]* mountedLayer
3636 mountL sync.Mutex
37+
38+ useTarSplit bool
3739}
3840
3941// StoreOptions are the options used to create a new Store instance
@@ -74,11 +76,17 @@ func NewStoreFromOptions(options StoreOptions) (Store, error) {
7476// metadata store and graph driver. The metadata store will be used to restore
7577// the Store.
7678func NewStoreFromGraphDriver (store MetadataStore , driver graphdriver.Driver ) (Store , error ) {
79+ caps := graphdriver.Capabilities {}
80+ if capDriver , ok := driver .(graphdriver.CapabilityDriver ); ok {
81+ caps = capDriver .Capabilities ()
82+ }
83+
7784 ls := & layerStore {
78- store : store ,
79- driver : driver ,
80- layerMap : map [ChainID ]* roLayer {},
81- mounts : map [string ]* mountedLayer {},
85+ store : store ,
86+ driver : driver ,
87+ layerMap : map [ChainID ]* roLayer {},
88+ mounts : map [string ]* mountedLayer {},
89+ useTarSplit : ! caps .ReproducesExactDiffs ,
8290 }
8391
8492 ids , mounts , err := store .List ()
@@ -207,18 +215,21 @@ func (ls *layerStore) applyTar(tx MetadataTransaction, ts io.Reader, parent stri
207215 digester := digest .Canonical .Digester ()
208216 tr := io .TeeReader (ts , digester .Hash ())
209217
210- tsw , err := tx .TarSplitWriter (true )
211- if err != nil {
212- return err
213- }
214- metaPacker := storage .NewJSONPacker (tsw )
215- defer tsw .Close ()
218+ rdr := tr
219+ if ls .useTarSplit {
220+ tsw , err := tx .TarSplitWriter (true )
221+ if err != nil {
222+ return err
223+ }
224+ metaPacker := storage .NewJSONPacker (tsw )
225+ defer tsw .Close ()
216226
217- // we're passing nil here for the file putter, because the ApplyDiff will
218- // handle the extraction of the archive
219- rdr , err := asm .NewInputTarStream (tr , metaPacker , nil )
220- if err != nil {
221- return err
227+ // we're passing nil here for the file putter, because the ApplyDiff will
228+ // handle the extraction of the archive
229+ rdr , err = asm .NewInputTarStream (tr , metaPacker , nil )
230+ if err != nil {
231+ return err
232+ }
222233 }
223234
224235 applySize , err := ls .driver .ApplyDiff (layer .cacheID , parent , rdr )
@@ -640,6 +651,34 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
640651 return initID , nil
641652}
642653
654+ func (ls * layerStore ) getTarStream (rl * roLayer ) (io.ReadCloser , error ) {
655+ if ! ls .useTarSplit {
656+ var parentCacheID string
657+ if rl .parent != nil {
658+ parentCacheID = rl .parent .cacheID
659+ }
660+
661+ return ls .driver .Diff (rl .cacheID , parentCacheID )
662+ }
663+
664+ r , err := ls .store .TarSplitReader (rl .chainID )
665+ if err != nil {
666+ return nil , err
667+ }
668+
669+ pr , pw := io .Pipe ()
670+ go func () {
671+ err := ls .assembleTarTo (rl .cacheID , r , nil , pw )
672+ if err != nil {
673+ pw .CloseWithError (err )
674+ } else {
675+ pw .Close ()
676+ }
677+ }()
678+
679+ return pr , nil
680+ }
681+
643682func (ls * layerStore ) assembleTarTo (graphID string , metadata io.ReadCloser , size * int64 , w io.Writer ) error {
644683 diffDriver , ok := ls .driver .(graphdriver.DiffGetterDriver )
645684 if ! ok {
0 commit comments