func ParseKeyHash(key_hash_string string) (uint64, uint32, error) { if len(key_hash_string)%2 == 1 { key_hash_string = "0" + key_hash_string } key_hash_bytes, khe := hex.DecodeString(key_hash_string) key_hash_len := len(key_hash_bytes) if khe != nil || key_hash_len <= 4 { glog.V(0).Infoln("Invalid key_hash", key_hash_string, "length:", key_hash_len, "error", khe) return 0, 0, errors.New("Invalid key and hash:" + key_hash_string) } key := util.BytesToUint64(key_hash_bytes[0 : key_hash_len-4]) hash := util.BytesToUint32(key_hash_bytes[key_hash_len-4 : key_hash_len]) return key, hash, nil }
func GetVolumeIdxEntries(server string, vid string, eachEntryFn func(key uint64, offset, size uint32)) error { values := make(url.Values) values.Add("volume", vid) line := make([]byte, 16) err := util.GetBufferStream("http://"+server+"/admin/sync/index", values, line, func(bytes []byte) { key := util.BytesToUint64(bytes[:8]) offset := util.BytesToUint32(bytes[8:12]) size := util.BytesToUint32(bytes[12:16]) eachEntryFn(key, offset, size) }) if err != nil { return err } return nil }
func (n *Needle) readNeedleDataVersion2(bytes []byte) { index, lenBytes := 0, len(bytes) if index < lenBytes { n.DataSize = util.BytesToUint32(bytes[index : index+4]) index = index + 4 if int(n.DataSize)+index > lenBytes { // this if clause is due to bug #87 and #93, fixed in v0.69 // remove this clause later return } n.Data = bytes[index : index+int(n.DataSize)] index = index + int(n.DataSize) n.Flags = bytes[index] index = index + 1 } if index < lenBytes && n.HasName() { n.NameSize = uint8(bytes[index]) index = index + 1 n.Name = bytes[index : index+int(n.NameSize)] index = index + int(n.NameSize) } if index < lenBytes && n.HasMime() { n.MimeSize = uint8(bytes[index]) index = index + 1 n.Mime = bytes[index : index+int(n.MimeSize)] index = index + int(n.MimeSize) } if index < lenBytes && n.HasLastModifiedDate() { n.LastModified = util.BytesToUint64(bytes[index : index+LastModifiedBytesLength]) index = index + LastModifiedBytesLength } if index < lenBytes && n.HasTtl() { n.Ttl = LoadTTLFromBytes(bytes[index : index+TtlBytesLength]) index = index + TtlBytesLength } }
func LoadNewNeedleMap(file *os.File) CompactMap { m := NewCompactMap() bytes := make([]byte, 16*1024) count, e := file.Read(bytes) if count > 0 { fstat, _ := file.Stat() glog.V(0).Infoln("Loading index file", fstat.Name(), "size", fstat.Size()) } for count > 0 && e == nil { for i := 0; i < count; i += 16 { key := util.BytesToUint64(bytes[i : i+8]) offset := util.BytesToUint32(bytes[i+8 : i+12]) size := util.BytesToUint32(bytes[i+12 : i+16]) if offset > 0 { m.Set(Key(key), offset, size) } else { //delete(m, key) } } count, e = file.Read(bytes) } return m }
func (n *Needle) ParseNeedleHeader(bytes []byte) { n.Cookie = util.BytesToUint32(bytes[0:4]) n.Id = util.BytesToUint64(bytes[4:12]) n.Size = util.BytesToUint32(bytes[12:NeedleHeaderSize]) }
func iterateEntries(datFile, idxFile *os.File, visitNeedle func(n *storage.Needle, offset int64)) { // start to read index file var readerOffset int64 bytes := make([]byte, 16) count, _ := idxFile.ReadAt(bytes, readerOffset) readerOffset += int64(count) // start to read dat file offset := int64(storage.SuperBlockSize) version := storage.Version2 n, rest, err := storage.ReadNeedleHeader(datFile, version, offset) if err != nil { fmt.Printf("cannot read needle header: %v", err) return } fmt.Printf("Needle %+v, rest %d\n", n, rest) for n != nil && count > 0 { // parse index file entry key := util.BytesToUint64(bytes[0:8]) offsetFromIndex := util.BytesToUint32(bytes[8:12]) sizeFromIndex := util.BytesToUint32(bytes[12:16]) count, _ = idxFile.ReadAt(bytes, readerOffset) readerOffset += int64(count) if offsetFromIndex != 0 && offset != int64(offsetFromIndex)*8 { //t := offset offset = int64(offsetFromIndex) * 8 //fmt.Printf("Offset change %d => %d\n", t, offset) } fmt.Printf("key: %d offsetFromIndex %d n.Size %d sizeFromIndex:%d\n", key, offsetFromIndex, n.Size, sizeFromIndex) padding := storage.NeedlePaddingSize - ((sizeFromIndex + storage.NeedleHeaderSize + storage.NeedleChecksumSize) % storage.NeedlePaddingSize) rest = sizeFromIndex + storage.NeedleChecksumSize + padding func() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) } }() if err = n.ReadNeedleBody(datFile, version, offset+int64(storage.NeedleHeaderSize), rest); err != nil { fmt.Printf("cannot read needle body: offset %d body %d %v\n", offset, rest, err) } }() if n.Size <= n.DataSize { continue } visitNeedle(n, offset) offset += int64(storage.NeedleHeaderSize) + int64(rest) //fmt.Printf("==> new entry offset %d\n", offset) if n, rest, err = storage.ReadNeedleHeader(datFile, version, offset); err != nil { if err == io.EOF { return } fmt.Printf("cannot read needle header: %v\n", err) return } //fmt.Printf("new entry needle size:%d rest:%d\n", n.Size, rest) } }
func idxFileEntry(bytes []byte) (key uint64, offset uint32, size uint32) { key = util.BytesToUint64(bytes[:8]) offset = util.BytesToUint32(bytes[8:12]) size = util.BytesToUint32(bytes[12:16]) return }