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.

101 lines
2.4 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
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"
  6. "sync/atomic"
  7. )
  8. var (
  9. _ = PageChunk(&MemChunk{})
  10. memChunkCounter int64
  11. )
  12. type MemChunk struct {
  13. sync.RWMutex
  14. buf []byte
  15. usage *ChunkWrittenIntervalList
  16. chunkSize int64
  17. logicChunkIndex LogicChunkIndex
  18. lastModifiedTsNs int64
  19. }
  20. func NewMemChunk(logicChunkIndex LogicChunkIndex, chunkSize int64) *MemChunk {
  21. atomic.AddInt64(&memChunkCounter, 1)
  22. return &MemChunk{
  23. logicChunkIndex: logicChunkIndex,
  24. chunkSize: chunkSize,
  25. buf: mem.Allocate(int(chunkSize)),
  26. usage: newChunkWrittenIntervalList(),
  27. }
  28. }
  29. func (mc *MemChunk) FreeResource() {
  30. mc.Lock()
  31. defer mc.Unlock()
  32. atomic.AddInt64(&memChunkCounter, -1)
  33. mem.Free(mc.buf)
  34. }
  35. func (mc *MemChunk) WriteDataAt(src []byte, offset int64, tsNs int64) (n int) {
  36. mc.Lock()
  37. defer mc.Unlock()
  38. if mc.lastModifiedTsNs > tsNs {
  39. println("write old data1", tsNs-mc.lastModifiedTsNs, "ns")
  40. }
  41. mc.lastModifiedTsNs = tsNs
  42. innerOffset := offset % mc.chunkSize
  43. n = copy(mc.buf[innerOffset:], src)
  44. mc.usage.MarkWritten(innerOffset, innerOffset+int64(n))
  45. return
  46. }
  47. func (mc *MemChunk) ReadDataAt(p []byte, off int64, tsNs int64) (maxStop int64) {
  48. mc.RLock()
  49. defer mc.RUnlock()
  50. memChunkBaseOffset := int64(mc.logicChunkIndex) * mc.chunkSize
  51. for t := mc.usage.head.next; t != mc.usage.tail; t = t.next {
  52. logicStart := max(off, int64(mc.logicChunkIndex)*mc.chunkSize+t.StartOffset)
  53. logicStop := min(off+int64(len(p)), memChunkBaseOffset+t.stopOffset)
  54. if logicStart < logicStop {
  55. if mc.lastModifiedTsNs > tsNs {
  56. copy(p[logicStart-off:logicStop-off], mc.buf[logicStart-memChunkBaseOffset:logicStop-memChunkBaseOffset])
  57. maxStop = max(maxStop, logicStop)
  58. } else {
  59. println("read old data1", tsNs-mc.lastModifiedTsNs, "ns")
  60. }
  61. }
  62. }
  63. return
  64. }
  65. func (mc *MemChunk) IsComplete() bool {
  66. mc.RLock()
  67. defer mc.RUnlock()
  68. return mc.usage.IsComplete(mc.chunkSize)
  69. }
  70. func (mc *MemChunk) LastModifiedTsNs() int64 {
  71. return mc.lastModifiedTsNs
  72. }
  73. func (mc *MemChunk) SaveContent(saveFn SaveToStorageFunc) {
  74. mc.RLock()
  75. defer mc.RUnlock()
  76. if saveFn == nil {
  77. return
  78. }
  79. for t := mc.usage.head.next; t != mc.usage.tail; t = t.next {
  80. reader := util.NewBytesReader(mc.buf[t.StartOffset:t.stopOffset])
  81. saveFn(reader, int64(mc.logicChunkIndex)*mc.chunkSize+t.StartOffset, t.Size(), mc.lastModifiedTsNs, func() {
  82. })
  83. }
  84. }