package txlog import ( "bytes" bin "gordenko.dev/dima/bin/little" ) const recordSize = 8 const chunkSize = 24 func copyPayloadFromChunks(w *bytes.Buffer, chunks [][]byte, size int, offset int) { bin.WriteUint16(w, uint16(size)) var ( chunkIdx = offset / chunkSize byteIdx = offset % chunkSize ) for _, chunk := range chunks[chunkIdx:] { available := len(chunk) - byteIdx if available <= size { w.Write(chunk[byteIdx:]) size -= available if size == 0 { return } byteIdx = 0 } else { w.Write(chunk[byteIdx : byteIdx+size]) return } } } ///////////////////////////////////////// // type DataPage struct { // PageNo uint32 // Reused bool // PrevPageNo uint32 // Checksum uint32 // Timestamps []byte // Values []byte // } // type IndexPage struct { // PageNo uint32 // Reused bool // Checksum uint32 // Records []byte // } // type IndexLevel struct { // Pages []IndexPage // Records []byte // unfilled // } // Для декодінга // type TxAppendedMeasures struct { // MetricID uint32 // DataPages []DataPage // // offsets потрібні тому що дані не додаються в кінець, а перезаписують кілька // // останніх байтів unfilled даних. Потрібно для коректного recovery. // // Якщо є DataPages, то застосовуються для 1-ї Data сторінки, інакше - до timestamps і values (unfilled) // TimestampsOffset int // ValuesOffset int // Timestamps []byte // unfilled // Values []byte // unfilled // IndexLevels []IndexLevel // } // func (s *TxAppendedMeasures) Read(r *bytes.Buffer) (err error) { // s.MetricID, err = bin.ReadUint32(r) // if err != nil { // return // } // dataPagesQty, err := bin.ReadVarSize(r) // if err != nil { // return // } // for range dataPagesQty { // var ( // p DataPage // timestampsSize, valuesSize int // //b byte // ) // p.PageNo, err = bin.ReadUint32(r) // if err != nil { // return // } // p.Reused, err = bin.ReadBool(r) // if err != nil { // return // } // p.PrevPageNo, err = bin.ReadUint32(r) // if err != nil { // return // } // p.Checksum, err = bin.ReadUint32(r) // if err != nil { // return // } // timestampsSize, err = bin.ReadUint16AsInt(r) // if err != nil { // return // } // p.Timestamps, err = bin.ReadN(r, timestampsSize) // if err != nil { // return // } // valuesSize, err = bin.ReadUint16AsInt(r) // if err != nil { // return // } // p.Values, err = bin.ReadN(r, valuesSize) // if err != nil { // return // } // s.DataPages = append(s.DataPages, p) // } // s.TimestampsOffset, err = bin.ReadUint16AsInt(r) // if err != nil { // return // } // s.ValuesOffset, err = bin.ReadUint16AsInt(r) // if err != nil { // return // } // var ( // timestampsSize, valuesSize int // ) // timestampsSize, err = bin.ReadVarSize(r) // if err != nil { // return // } // s.Timestamps, err = bin.ReadN(r, timestampsSize) // if err != nil { // return // } // valuesSize, err = bin.ReadVarSize(r) // if err != nil { // return // } // s.Values, err = bin.ReadN(r, valuesSize) // if err != nil { // return // } // if len(s.DataPages) == 0 { // return // } // indexLevelsQty, err := bin.ReadVarSize(r) // if err != nil { // return // } // for range indexLevelsQty { // var ( // indexPagesQty int // level IndexLevel // recordsQty int // ) // indexPagesQty, err = bin.ReadVarSize(r) // if err != nil { // return // } // for range indexPagesQty { // var ( // p IndexPage // recordsQty int // ) // p.PageNo, err = bin.ReadUint32(r) // if err != nil { // return // } // p.Reused, err = bin.ReadBool(r) // if err != nil { // return // } // p.Checksum, err = bin.ReadUint32(r) // if err != nil { // return // } // recordsQty, err = bin.ReadVarSize(r) // if err != nil { // return // } // p.Records, err = bin.ReadN(r, recordsQty*recordSize) // if err != nil { // return // } // level.Pages = append(level.Pages, p) // } // recordsQty, err = bin.ReadVarSize(r) // if err != nil { // return // } // level.Records, err = bin.ReadN(r, recordsQty*recordSize) // if err != nil { // return // } // s.IndexLevels = append(s.IndexLevels, level) // } // return // }