blob.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Package blob defines a common data interchange type for keyvalue FS's.
  2. package blob
  3. // Blob is a binary blob of data that can support platform-optimized mutations for better performance.
  4. type Blob interface {
  5. // Bytes returns the byte slice equivalent to the data in this Blob.
  6. Bytes() []byte
  7. // Len returns the number of bytes contained in this blob.
  8. // Can be used to avoid unnecessary conversions and allocations from len(Bytes()).
  9. Len() int
  10. }
  11. // ViewBlob is a Blob that can return a view into the same underlying data.
  12. // Mutating the returned Blob also mutates the original.
  13. type ViewBlob interface {
  14. Blob
  15. View(start, end int64) (Blob, error)
  16. }
  17. // SliceBlob is a Blob that can return a copy of the data between start and end.
  18. type SliceBlob interface {
  19. Blob
  20. Slice(start, end int64) (Blob, error)
  21. }
  22. // SetBlob is a Blob that can copy 'src' into itself starting at the given offset into this Blob.
  23. // Use View() on 'src' to control the maximum that is copied into this Blob.
  24. type SetBlob interface {
  25. Blob
  26. Set(src Blob, offset int64) (n int, err error)
  27. }
  28. // GrowBlob is a Blob that can increase it's size by allocating offset bytes at the end.
  29. type GrowBlob interface {
  30. Blob
  31. Grow(offset int64) error
  32. }
  33. // TruncateBlob is a Blob that can cut off bytes from the end until it is 'size' bytes long.
  34. type TruncateBlob interface {
  35. Blob
  36. Truncate(size int64) error
  37. }
  38. // View attempts to call an optimized blob.View(), falls back to copying into Bytes and running Bytes.View().
  39. func View(b Blob, start, end int64) (Blob, error) {
  40. if b, ok := b.(ViewBlob); ok {
  41. return b.View(start, end)
  42. }
  43. return NewBytes(b.Bytes()).View(start, end)
  44. }
  45. // Slice attempts to call an optimized blob.Slice(), falls back to copying into Bytes and running Bytes.Slice().
  46. func Slice(b Blob, start, end int64) (Blob, error) {
  47. if b, ok := b.(SliceBlob); ok {
  48. return b.Slice(start, end)
  49. }
  50. return NewBytes(b.Bytes()).Slice(start, end)
  51. }
  52. // Set attempts to call an optimized blob.Set(), falls back to copying into Bytes and running Bytes.Set().
  53. func Set(dest Blob, src Blob, offset int64) (n int, err error) {
  54. if dest, ok := dest.(SetBlob); ok {
  55. return dest.Set(src, offset)
  56. }
  57. return NewBytes(dest.Bytes()).Set(src, offset)
  58. }
  59. // Grow attempts to call an optimized blob.Grow(), falls back to copying into Bytes and running Bytes.Grow().
  60. func Grow(b Blob, offset int64) error {
  61. if b, ok := b.(GrowBlob); ok {
  62. return b.Grow(offset)
  63. }
  64. return NewBytes(b.Bytes()).Grow(offset)
  65. }
  66. // Truncate attempts to call an optimized blob.Truncate(), falls back to copying into Bytes and running Bytes.Truncate().
  67. func Truncate(b Blob, size int64) error {
  68. if b, ok := b.(TruncateBlob); ok {
  69. return b.Truncate(size)
  70. }
  71. return NewBytes(b.Bytes()).Truncate(size)
  72. }