MCPcopy
hub / github.com/perkeep/perkeep / writeAZip

Method writeAZip

pkg/blobserver/blobpacked/blobpacked.go:1310–1508  ·  view source on GitHub ↗

trunc is a hint about which blob to truncate after. It may be zero. If the returned error is of type 'needsTruncatedAfterError', then the zip should be attempted to be written again, but truncating the data after the listed blob.

(ctx context.Context, trunc blob.Ref)

Source from the content-addressed store, hash-verified

1308// the zip should be attempted to be written again, but truncating the
1309// data after the listed blob.
1310func (pk *packer) writeAZip(ctx context.Context, trunc blob.Ref) (err error) {
1311 defer func() {
1312 if e := recover(); e != nil {
1313 if v, ok := e.(error); ok && err == nil {
1314 err = v
1315 } else {
1316 panic(e)
1317 }
1318 }
1319 }()
1320 mf := Manifest{
1321 WholeRef: pk.wholeRef,
1322 WholeSize: pk.wholeSize,
1323 WholePartIndex: len(pk.zips),
1324 }
1325 var zbuf bytes.Buffer
1326 cw := &countWriter{w: &zbuf}
1327 zw := zip.NewWriter(cw)
1328
1329 var approxSize = zipFixedOverhead // can't use zbuf.Len because zw buffers
1330 var dataRefsWritten []blob.Ref
1331 var dataBytesWritten int64
1332 var schemaBlobSeen = map[blob.Ref]bool{}
1333 var schemaBlobs []blob.Ref // to add after the main file
1334
1335 baseFileName := pk.fr.FileName()
1336 if strings.Contains(baseFileName, "/") || strings.Contains(baseFileName, "\\") {
1337 return fmt.Errorf("File schema blob %v filename had a slash in it: %q", pk.fr.SchemaBlobRef(), baseFileName)
1338 }
1339 fh := &zip.FileHeader{
1340 Name: baseFileName,
1341 Method: zip.Store, // uncompressed
1342 Modified: pk.fr.ModTime(),
1343 }
1344 fh.SetMode(0644)
1345 fw, err := zw.CreateHeader(fh)
1346 check(err)
1347 check(zw.Flush())
1348 dataStart := cw.n
1349 approxSize += zipPerEntryOverhead // for the first FileHeader w/ the data
1350
1351 zipMax := pk.s.maxZipBlobSize()
1352 chunks := pk.chunksRemain
1353 chunkWholeHash := blob.NewHash()
1354 for len(chunks) > 0 {
1355 dr := chunks[0] // the next chunk to maybe write
1356
1357 if trunc.Valid() && trunc == dr {
1358 if approxSize == 0 {
1359 return errors.New("first blob is too large to pack, once you add the zip overhead")
1360 }
1361 break
1362 }
1363
1364 schemaBlobsSave := schemaBlobs
1365 for _, parent := range pk.schemaParent[dr] {
1366 if !schemaBlobSeen[parent] {
1367 schemaBlobSeen[parent] = true

Callers 1

packMethod · 0.95

Calls 15

approxSerializedSizeMethod · 0.95
NewHashFunction · 0.92
RefFromHashFunction · 0.92
RefFromBytesFunction · 0.92
ReceiveNoHashFunction · 0.92
ContainsMethod · 0.80
SchemaBlobRefMethod · 0.80
maxZipBlobSizeMethod · 0.80
ReadAllMethod · 0.80
CreateMethod · 0.80
LogfMethod · 0.80
checkFunction · 0.70

Tested by

no test coverage detected