2019-11-09 08:10:59 +00:00
|
|
|
package memory_map
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/backend"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2019-11-29 02:33:18 +00:00
|
|
|
_ backend.BackendStorageFile = &MemoryMappedFile{}
|
2019-11-09 08:10:59 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type MemoryMappedFile struct {
|
|
|
|
mm *MemoryMap
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMemoryMappedFile(f *os.File, memoryMapSizeMB uint32) *MemoryMappedFile {
|
|
|
|
mmf := &MemoryMappedFile{
|
2019-11-12 06:21:43 +00:00
|
|
|
mm: new(MemoryMap),
|
2019-11-09 08:10:59 +00:00
|
|
|
}
|
|
|
|
mmf.mm.CreateMemoryMap(f, 1024*1024*uint64(memoryMapSizeMB))
|
|
|
|
return mmf
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mmf *MemoryMappedFile) ReadAt(p []byte, off int64) (n int, err error) {
|
2019-11-12 06:21:43 +00:00
|
|
|
readBytes, e := mmf.mm.ReadMemory(uint64(off), uint64(len(p)))
|
2019-11-09 08:10:59 +00:00
|
|
|
if e != nil {
|
|
|
|
return 0, e
|
|
|
|
}
|
|
|
|
// TODO avoid the extra copy
|
|
|
|
copy(p, readBytes)
|
|
|
|
return len(readBytes), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mmf *MemoryMappedFile) WriteAt(p []byte, off int64) (n int, err error) {
|
|
|
|
mmf.mm.WriteMemory(uint64(off), uint64(len(p)), p)
|
|
|
|
return len(p), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mmf *MemoryMappedFile) Truncate(off int64) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mmf *MemoryMappedFile) Close() error {
|
|
|
|
mmf.mm.DeleteFileAndMemoryMap()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mmf *MemoryMappedFile) GetStat() (datSize int64, modTime time.Time, err error) {
|
|
|
|
stat, e := mmf.mm.File.Stat()
|
|
|
|
if e == nil {
|
2019-11-22 22:51:09 +00:00
|
|
|
return mmf.mm.End_of_file + 1, stat.ModTime(), nil
|
2019-11-09 08:10:59 +00:00
|
|
|
}
|
|
|
|
return 0, time.Time{}, err
|
|
|
|
}
|
|
|
|
|
2019-12-09 03:44:16 +00:00
|
|
|
func (mmf *MemoryMappedFile) Name() string {
|
2019-11-09 08:10:59 +00:00
|
|
|
return mmf.mm.File.Name()
|
|
|
|
}
|