123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package super_block
- import (
- "github.com/golang/protobuf/proto"
- "github.com/chrislusf/seaweedfs/weed/glog"
- "github.com/chrislusf/seaweedfs/weed/pb/master_pb"
- "github.com/chrislusf/seaweedfs/weed/storage/needle"
- "github.com/chrislusf/seaweedfs/weed/util"
- )
- const (
- SuperBlockSize = 8
- )
- /*
- * Super block currently has 8 bytes allocated for each volume.
- * Byte 0: version, 1 or 2
- * Byte 1: Replica Placement strategy, 000, 001, 002, 010, etc
- * Byte 2 and byte 3: Time to live. See TTL for definition
- * Byte 4 and byte 5: The number of times the volume has been compacted.
- * Rest bytes: Reserved
- */
- type SuperBlock struct {
- Version needle.Version
- ReplicaPlacement *ReplicaPlacement
- Ttl *needle.TTL
- CompactionRevision uint16
- Extra *master_pb.SuperBlockExtra
- ExtraSize uint16
- }
- func (s *SuperBlock) BlockSize() int {
- switch s.Version {
- case needle.Version2, needle.Version3:
- return SuperBlockSize + int(s.ExtraSize)
- }
- return SuperBlockSize
- }
- func (s *SuperBlock) Bytes() []byte {
- header := make([]byte, SuperBlockSize)
- header[0] = byte(s.Version)
- header[1] = s.ReplicaPlacement.Byte()
- s.Ttl.ToBytes(header[2:4])
- util.Uint16toBytes(header[4:6], s.CompactionRevision)
- if s.Extra != nil {
- extraData, err := proto.Marshal(s.Extra)
- if err != nil {
- glog.Fatalf("cannot marshal super block extra %+v: %v", s.Extra, err)
- }
- extraSize := len(extraData)
- if extraSize > 256*256-2 {
- // reserve a couple of bits for future extension
- glog.Fatalf("super block extra size is %d bigger than %d", extraSize, 256*256-2)
- }
- s.ExtraSize = uint16(extraSize)
- util.Uint16toBytes(header[6:8], s.ExtraSize)
- header = append(header, extraData...)
- }
- return header
- }
- func (s *SuperBlock) Initialized() bool {
- return s.ReplicaPlacement != nil && s.Ttl != nil
- }
|