|
@ -0,0 +1,78 @@ |
|
|
|
|
|
package filesys |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/filesys/page_writer" |
|
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/glog" |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type PageWriter struct { |
|
|
|
|
|
f *File |
|
|
|
|
|
collection string |
|
|
|
|
|
replication string |
|
|
|
|
|
chunkSize int64 |
|
|
|
|
|
writerPattern *WriterPattern |
|
|
|
|
|
|
|
|
|
|
|
randomWriter page_writer.DirtyPages |
|
|
|
|
|
streamWriter page_writer.DirtyPages |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
|
_ = page_writer.DirtyPages(&PageWriter{}) |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
func newPageWriter(file *File, chunkSize int64) *PageWriter { |
|
|
|
|
|
pw := &PageWriter{ |
|
|
|
|
|
f: file, |
|
|
|
|
|
chunkSize: chunkSize, |
|
|
|
|
|
randomWriter: newTempFileDirtyPages(file), |
|
|
|
|
|
streamWriter: newContinuousDirtyPages(file), |
|
|
|
|
|
writerPattern: NewWriterPattern(file.Name, chunkSize), |
|
|
|
|
|
} |
|
|
|
|
|
return pw |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (pw *PageWriter) AddPage(offset int64, data []byte) { |
|
|
|
|
|
|
|
|
|
|
|
glog.V(4).Infof("AddPage %v [%d, %d) streaming:%v", pw.f.fullpath(), offset, offset+int64(len(data)), pw.writerPattern.IsStreamingMode()) |
|
|
|
|
|
|
|
|
|
|
|
pw.writerPattern.MonitorWriteAt(offset, len(data)) |
|
|
|
|
|
|
|
|
|
|
|
chunkIndex := offset / pw.chunkSize |
|
|
|
|
|
for i := chunkIndex; len(data) > 0; i++ { |
|
|
|
|
|
writeSize := min(int64(len(data)), (i+1)*pw.chunkSize-offset) |
|
|
|
|
|
pw.addToOneChunk(i, offset, data[:writeSize]) |
|
|
|
|
|
offset += writeSize |
|
|
|
|
|
data = data[writeSize:] |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (pw *PageWriter) addToOneChunk(chunkIndex, offset int64, data []byte) { |
|
|
|
|
|
if chunkIndex > 0 { |
|
|
|
|
|
if pw.writerPattern.IsStreamingMode() { |
|
|
|
|
|
pw.streamWriter.AddPage(offset, data) |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
pw.randomWriter.AddPage(offset, data) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (pw *PageWriter) FlushData() error { |
|
|
|
|
|
if err := pw.streamWriter.FlushData(); err != nil { |
|
|
|
|
|
return err |
|
|
|
|
|
} |
|
|
|
|
|
return pw.randomWriter.FlushData() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (pw *PageWriter) ReadDirtyDataAt(data []byte, startOffset int64) (maxStop int64) { |
|
|
|
|
|
glog.V(4).Infof("ReadDirtyDataAt %v [%d, %d)", pw.f.fullpath(), startOffset, startOffset+int64(len(data))) |
|
|
|
|
|
m1 := pw.streamWriter.ReadDirtyDataAt(data, startOffset) |
|
|
|
|
|
m2 := pw.randomWriter.ReadDirtyDataAt(data, startOffset) |
|
|
|
|
|
return max(m1, m2) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (pw *PageWriter) GetStorageOptions() (collection, replication string) { |
|
|
|
|
|
if pw.writerPattern.IsStreamingMode() { |
|
|
|
|
|
return pw.streamWriter.GetStorageOptions() |
|
|
|
|
|
} |
|
|
|
|
|
return pw.randomWriter.GetStorageOptions() |
|
|
|
|
|
} |