needle_write_v2.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package needle
  2. import (
  3. "bytes"
  4. "math"
  5. . "github.com/seaweedfs/seaweedfs/weed/storage/types"
  6. "github.com/seaweedfs/seaweedfs/weed/util"
  7. )
  8. func writeNeedleV2(n *Needle, offset uint64, bytesBuffer *bytes.Buffer) (size Size, actualSize int64, err error) {
  9. return writeNeedleCommon(n, offset, bytesBuffer, Version2, func(n *Needle, header []byte, bytesBuffer *bytes.Buffer, padding int) {
  10. util.Uint32toBytes(header[0:NeedleChecksumSize], uint32(n.Checksum))
  11. bytesBuffer.Write(header[0 : NeedleChecksumSize+padding])
  12. })
  13. }
  14. func writeNeedleCommon(n *Needle, offset uint64, bytesBuffer *bytes.Buffer, version Version, writeFooter func(n *Needle, header []byte, bytesBuffer *bytes.Buffer, padding int)) (size Size, actualSize int64, err error) {
  15. bytesBuffer.Reset()
  16. header := make([]byte, NeedleHeaderSize+TimestampSize)
  17. CookieToBytes(header[0:CookieSize], n.Cookie)
  18. NeedleIdToBytes(header[CookieSize:CookieSize+NeedleIdSize], n.Id)
  19. if len(n.Name) >= math.MaxUint8 {
  20. n.NameSize = math.MaxUint8
  21. } else {
  22. n.NameSize = uint8(len(n.Name))
  23. }
  24. n.DataSize, n.MimeSize = uint32(len(n.Data)), uint8(len(n.Mime))
  25. if n.DataSize > 0 {
  26. n.Size = 4 + Size(n.DataSize) + 1
  27. if n.HasName() {
  28. n.Size = n.Size + 1 + Size(n.NameSize)
  29. }
  30. if n.HasMime() {
  31. n.Size = n.Size + 1 + Size(n.MimeSize)
  32. }
  33. if n.HasLastModifiedDate() {
  34. n.Size = n.Size + LastModifiedBytesLength
  35. }
  36. if n.HasTtl() {
  37. n.Size = n.Size + TtlBytesLength
  38. }
  39. if n.HasPairs() {
  40. n.Size += 2 + Size(n.PairsSize)
  41. }
  42. } else {
  43. n.Size = 0
  44. }
  45. SizeToBytes(header[CookieSize+NeedleIdSize:CookieSize+NeedleIdSize+SizeSize], n.Size)
  46. bytesBuffer.Write(header[0:NeedleHeaderSize])
  47. if n.DataSize > 0 {
  48. util.Uint32toBytes(header[0:4], n.DataSize)
  49. bytesBuffer.Write(header[0:4])
  50. bytesBuffer.Write(n.Data)
  51. util.Uint8toBytes(header[0:1], n.Flags)
  52. bytesBuffer.Write(header[0:1])
  53. if n.HasName() {
  54. util.Uint8toBytes(header[0:1], n.NameSize)
  55. bytesBuffer.Write(header[0:1])
  56. bytesBuffer.Write(n.Name[:n.NameSize])
  57. }
  58. if n.HasMime() {
  59. util.Uint8toBytes(header[0:1], n.MimeSize)
  60. bytesBuffer.Write(header[0:1])
  61. bytesBuffer.Write(n.Mime)
  62. }
  63. if n.HasLastModifiedDate() {
  64. util.Uint64toBytes(header[0:8], n.LastModified)
  65. bytesBuffer.Write(header[8-LastModifiedBytesLength : 8])
  66. }
  67. if n.HasTtl() && n.Ttl != nil {
  68. n.Ttl.ToBytes(header[0:TtlBytesLength])
  69. bytesBuffer.Write(header[0:TtlBytesLength])
  70. }
  71. if n.HasPairs() {
  72. util.Uint16toBytes(header[0:2], n.PairsSize)
  73. bytesBuffer.Write(header[0:2])
  74. bytesBuffer.Write(n.Pairs)
  75. }
  76. }
  77. padding := PaddingLength(n.Size, version)
  78. writeFooter(n, header, bytesBuffer, int(padding))
  79. size = Size(n.DataSize)
  80. actualSize = GetActualSize(n.Size, version)
  81. return size, actualSize, nil
  82. }