/weed-fs/src/pkg/storage/store.go

http://weed-fs.googlecode.com/ · Go · 102 lines · 97 code · 5 blank · 0 comment · 15 complexity · 59649af72491ed21c86d4da2df95be61 MD5 · raw file

  1. package storage
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "log"
  6. "net/url"
  7. "strconv"
  8. "strings"
  9. "pkg/util"
  10. )
  11. type Store struct {
  12. volumes map[uint64]*Volume
  13. dir string
  14. Port int
  15. PublicUrl string
  16. }
  17. type VolumeInfo struct {
  18. Id uint32
  19. Size int64
  20. }
  21. func NewStore(port int, publicUrl, dirname string, volumeListString string) (s *Store) {
  22. s = &Store{Port: port, PublicUrl: publicUrl, dir: dirname}
  23. s.volumes = make(map[uint64]*Volume)
  24. s.AddVolume(volumeListString)
  25. log.Println("Store started on dir:", dirname, "with", len(s.volumes), "volumes")
  26. return
  27. }
  28. func (s *Store) AddVolume(volumeListString string) error {
  29. for _, range_string := range strings.Split(volumeListString, ",") {
  30. if strings.Index(range_string, "-") < 0 {
  31. id_string := range_string
  32. id, err := strconv.ParseUint(id_string, 10, 64)
  33. if err != nil {
  34. return errors.New("Volume Id " + id_string + " is not a valid unsigned integer!")
  35. }
  36. s.addVolume(id)
  37. } else {
  38. pair := strings.Split(range_string, "-")
  39. start, start_err := strconv.ParseUint(pair[0], 10, 64)
  40. if start_err != nil {
  41. return errors.New("Volume Start Id" + pair[0] + " is not a valid unsigned integer!")
  42. }
  43. end, end_err := strconv.ParseUint(pair[1], 10, 64)
  44. if end_err != nil {
  45. return errors.New("Volume End Id" + pair[1] + " is not a valid unsigned integer!")
  46. }
  47. for id := start; id <= end; id++ {
  48. s.addVolume(id)
  49. }
  50. }
  51. }
  52. return nil
  53. }
  54. func (s *Store) addVolume(vid uint64) error {
  55. if s.volumes[vid] != nil {
  56. return errors.New("Volume Id " + strconv.FormatUint(vid, 10) + " already exists!")
  57. }
  58. s.volumes[vid] = NewVolume(s.dir, uint32(vid))
  59. return nil
  60. }
  61. func (s *Store) Status() *[]*VolumeInfo {
  62. stats := new([]*VolumeInfo)
  63. for k, v := range s.volumes {
  64. s := new(VolumeInfo)
  65. s.Id, s.Size = uint32(k), v.Size()
  66. *stats = append(*stats, s)
  67. }
  68. return stats
  69. }
  70. func (s *Store) Join(mserver string) {
  71. stats := new([]*VolumeInfo)
  72. for k, v := range s.volumes {
  73. s := new(VolumeInfo)
  74. s.Id, s.Size = uint32(k), v.Size()
  75. *stats = append(*stats, s)
  76. }
  77. bytes, _ := json.Marshal(stats)
  78. values := make(url.Values)
  79. values.Add("port", strconv.Itoa(s.Port))
  80. values.Add("publicUrl", s.PublicUrl)
  81. values.Add("volumes", string(bytes))
  82. util.Post("http://"+mserver+"/dir/join", values)
  83. }
  84. func (s *Store) Close() {
  85. for _, v := range s.volumes {
  86. v.Close()
  87. }
  88. }
  89. func (s *Store) Write(i uint64, n *Needle) uint32 {
  90. return s.volumes[i].write(n)
  91. }
  92. func (s *Store) Delete(i uint64, n *Needle) uint32 {
  93. return s.volumes[i].delete(n)
  94. }
  95. func (s *Store) Read(i uint64, n *Needle) (int, error) {
  96. return s.volumes[i].read(n)
  97. }