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.

83 lines
2.4 KiB

6 years ago
6 years ago
6 years ago
7 years ago
  1. package storage
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "sync"
  7. "github.com/chrislusf/seaweedfs/weed/storage/needle_map"
  8. . "github.com/chrislusf/seaweedfs/weed/storage/types"
  9. "github.com/chrislusf/seaweedfs/weed/util"
  10. )
  11. type NeedleMapType int
  12. const (
  13. NeedleMapInMemory NeedleMapType = iota
  14. NeedleMapLevelDb // small memory footprint, 4MB total, 1 write buffer, 3 block buffer
  15. NeedleMapLevelDbMedium // medium memory footprint, 8MB total, 3 write buffer, 5 block buffer
  16. NeedleMapLevelDbLarge // large memory footprint, 12MB total, 4write buffer, 8 block buffer
  17. )
  18. type NeedleMapper interface {
  19. Put(key NeedleId, offset Offset, size uint32) error
  20. Get(key NeedleId) (element *needle_map.NeedleValue, ok bool)
  21. Delete(key NeedleId, offset Offset) error
  22. Close()
  23. Destroy() error
  24. ContentSize() uint64
  25. DeletedSize() uint64
  26. FileCount() int
  27. DeletedCount() int
  28. MaxFileKey() NeedleId
  29. IndexFileSize() uint64
  30. IndexFileContent() ([]byte, error)
  31. IndexFileName() string
  32. }
  33. type baseNeedleMapper struct {
  34. indexFile *os.File
  35. indexFileAccessLock sync.Mutex
  36. mapMetric
  37. }
  38. func (nm *baseNeedleMapper) IndexFileSize() uint64 {
  39. stat, err := nm.indexFile.Stat()
  40. if err == nil {
  41. return uint64(stat.Size())
  42. }
  43. return 0
  44. }
  45. func (nm *baseNeedleMapper) IndexFileName() string {
  46. return nm.indexFile.Name()
  47. }
  48. func IdxFileEntry(bytes []byte) (key NeedleId, offset Offset, size uint32) {
  49. key = BytesToNeedleId(bytes[:NeedleIdSize])
  50. offset = BytesToOffset(bytes[NeedleIdSize : NeedleIdSize+OffsetSize])
  51. size = util.BytesToUint32(bytes[NeedleIdSize+OffsetSize : NeedleIdSize+OffsetSize+SizeSize])
  52. return
  53. }
  54. func (nm *baseNeedleMapper) appendToIndexFile(key NeedleId, offset Offset, size uint32) error {
  55. bytes := make([]byte, NeedleIdSize+OffsetSize+SizeSize)
  56. NeedleIdToBytes(bytes[0:NeedleIdSize], key)
  57. OffsetToBytes(bytes[NeedleIdSize:NeedleIdSize+OffsetSize], offset)
  58. util.Uint32toBytes(bytes[NeedleIdSize+OffsetSize:NeedleIdSize+OffsetSize+SizeSize], size)
  59. nm.indexFileAccessLock.Lock()
  60. defer nm.indexFileAccessLock.Unlock()
  61. if _, err := nm.indexFile.Seek(0, 2); err != nil {
  62. return fmt.Errorf("cannot seek end of indexfile %s: %v",
  63. nm.indexFile.Name(), err)
  64. }
  65. _, err := nm.indexFile.Write(bytes)
  66. return err
  67. }
  68. func (nm *baseNeedleMapper) IndexFileContent() ([]byte, error) {
  69. nm.indexFileAccessLock.Lock()
  70. defer nm.indexFileAccessLock.Unlock()
  71. return ioutil.ReadFile(nm.indexFile.Name())
  72. }