You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.9 KiB

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