page_chunk_mem.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package page_writer
  2. import (
  3. "github.com/chrislusf/seaweedfs/weed/util"
  4. "github.com/chrislusf/seaweedfs/weed/util/mem"
  5. )
  6. var (
  7. _ = PageChunk(&MemChunk{})
  8. )
  9. type MemChunk struct {
  10. buf []byte
  11. usage *ChunkWrittenIntervalList
  12. chunkSize int64
  13. logicChunkIndex LogicChunkIndex
  14. }
  15. func NewMemChunk(logicChunkIndex LogicChunkIndex, chunkSize int64) *MemChunk {
  16. return &MemChunk{
  17. logicChunkIndex: logicChunkIndex,
  18. chunkSize: chunkSize,
  19. buf: mem.Allocate(int(chunkSize)),
  20. usage: newChunkWrittenIntervalList(),
  21. }
  22. }
  23. func (mc *MemChunk) FreeResource() {
  24. mem.Free(mc.buf)
  25. }
  26. func (mc *MemChunk) WriteDataAt(src []byte, offset int64) (n int) {
  27. innerOffset := offset % mc.chunkSize
  28. n = copy(mc.buf[innerOffset:], src)
  29. mc.usage.MarkWritten(innerOffset, innerOffset+int64(n))
  30. return
  31. }
  32. func (mc *MemChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
  33. memChunkBaseOffset := int64(mc.logicChunkIndex) * mc.chunkSize
  34. for t := mc.usage.head.next; t != mc.usage.tail; t = t.next {
  35. logicStart := max(off, int64(mc.logicChunkIndex)*mc.chunkSize+t.StartOffset)
  36. logicStop := min(off+int64(len(p)), memChunkBaseOffset+t.stopOffset)
  37. if logicStart < logicStop {
  38. copy(p[logicStart-off:logicStop-off], mc.buf[logicStart-memChunkBaseOffset:logicStop-memChunkBaseOffset])
  39. maxStop = max(maxStop, logicStop)
  40. }
  41. }
  42. return
  43. }
  44. func (mc *MemChunk) IsComplete() bool {
  45. return mc.usage.IsComplete(mc.chunkSize)
  46. }
  47. func (mc *MemChunk) WrittenSize() int64 {
  48. return mc.usage.WrittenSize()
  49. }
  50. func (mc *MemChunk) SaveContent(saveFn SaveToStorageFunc) {
  51. if saveFn == nil {
  52. return
  53. }
  54. for t := mc.usage.head.next; t != mc.usage.tail; t = t.next {
  55. reader := util.NewBytesReader(mc.buf[t.StartOffset:t.stopOffset])
  56. saveFn(reader, int64(mc.logicChunkIndex)*mc.chunkSize+t.StartOffset, t.Size(), func() {
  57. })
  58. }
  59. }