diff options
| author | 2026-03-26 09:17:14 +0000 | |
|---|---|---|
| committer | 2026-03-26 09:18:30 +0000 | |
| commit | 3e884f5f3d42cbc4874a04da31dde10314b0cfad (patch) | |
| tree | f5e1e325fd1a2a0801791c054010213214475d80 /format/packfile/ingest/thin_append.go | |
| parent | network/receivepack: Rename from receivepack (diff) | |
| signature | No signature | |
format: Move commitgraph and packfile here
Diffstat (limited to 'format/packfile/ingest/thin_append.go')
| -rw-r--r-- | format/packfile/ingest/thin_append.go | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/format/packfile/ingest/thin_append.go b/format/packfile/ingest/thin_append.go new file mode 100644 index 00000000..779d477f --- /dev/null +++ b/format/packfile/ingest/thin_append.go @@ -0,0 +1,91 @@ +package ingest + +import ( + "compress/zlib" + "hash/crc32" + "io" + + "codeberg.org/lindenii/furgit/internal/intconv" + objectid "codeberg.org/lindenii/furgit/object/id" + objecttype "codeberg.org/lindenii/furgit/object/type" +) + +// appendBaseObject appends one base object as a new packed non-delta entry. +func appendBaseObject(state *ingestState, id objectid.ObjectID, realType objecttype.Type, content []byte) (int, error) { + start := state.stream.consumed + + header := encodePackEntryHeader(realType, int64(len(content))) + + startInt64, err := intconv.Uint64ToInt64(start) + if err != nil { + return 0, err + } + + _, err = state.packFile.WriteAt(header, startInt64) + if err != nil { + return 0, err + } + + headerLenInt64 := int64(len(header)) + section := &fileSectionWriter{file: state.packFile, off: startInt64 + headerLenInt64} + crc := crc32.NewIEEE() + + _, err = crc.Write(header) + if err != nil { + return 0, err + } + + counting := &countingWriter{dst: section} + + zw := zlib.NewWriter(io.MultiWriter(counting, crc)) + + _, err = zw.Write(content) + if err != nil { + return 0, err + } + + err = zw.Close() + if err != nil { + return 0, err + } + + headerLenUint64, err := intconv.IntToUint64(len(header)) + if err != nil { + return 0, err + } + + countingNUint64, err := intconv.IntToUint64(counting.n) + if err != nil { + return 0, err + } + + packedLen := headerLenUint64 + countingNUint64 + end := start + packedLen + state.stream.consumed = end + + headerLenUint32, err := intconv.IntToUint32(len(header)) + if err != nil { + return 0, err + } + + record := objectRecord{ + offset: start, + headerLen: headerLenUint32, + packedLen: packedLen, + crc32: crc.Sum32(), + packedType: realType, + realType: realType, + declaredSize: int64(len(content)), + dataOffset: start + headerLenUint64, + objectID: id, + resolved: true, + } + + recordIdx := len(state.records) + state.records = append(state.records, record) + state.offsetToRecord[start] = recordIdx + state.objectToRecord[id] = recordIdx + state.baseCache.add(recordIdx, realType, content) + + return recordIdx, nil +} |
