func (nm *NeedleMap) Delete(key uint64) { delete(nm.m, key) util.Uint64toBytes(nm.bytes[0:8], key) util.Uint32toBytes(nm.bytes[8:12], 0) util.Uint32toBytes(nm.bytes[12:16], 0) nm.indexFile.Write(nm.bytes) }
func (nm *NeedleMap) Put(key uint64, offset uint32, size uint32) (int, error) { nm.m[key] = &NeedleValue{Offset: offset, Size: size} util.Uint64toBytes(nm.bytes[0:8], key) util.Uint32toBytes(nm.bytes[8:12], offset) util.Uint32toBytes(nm.bytes[12:16], size) return nm.indexFile.Write(nm.bytes) }
// dumps a NeedleMap into a cdb func DumpNeedleMapToCdb(cdbName string, nm *NeedleMap) error { tempnam := cdbName + "t" fnames := make([]string, 1, 2) adder, closer, err := openTempCdb(tempnam) if err != nil { return fmt.Errorf("error creating factory: %s", err) } fnames[0] = tempnam elt := cdb.Element{Key: make([]byte, 8), Data: make([]byte, 8)} fcount := uint64(0) walk := func(key uint64, offset, size uint32) error { if fcount >= maxCdbRecCount { if err = closer(); err != nil { return err } tempnam = cdbName + "t2" if adder, closer, err = openTempCdb(tempnam); err != nil { return fmt.Errorf("error creating second factory: %s", err) } fnames = append(fnames, tempnam) fcount = 0 } util.Uint64toBytes(elt.Key, key) util.Uint32toBytes(elt.Data[:4], offset) util.Uint32toBytes(elt.Data[4:], size) fcount++ return adder(elt) } // and write out the cdb from there err = nm.Visit(func(nv NeedleValue) error { return walk(uint64(nv.Key), nv.Offset, nv.Size) }) if err != nil { closer() return fmt.Errorf("error walking index %s: %s", nm, err) } // store fileBytes data, e := json.Marshal(nm.mapMetric) if e != nil { return fmt.Errorf("error marshaling metric %s: %s", nm.mapMetric, e) } if err = adder(cdb.Element{Key: []byte{'M'}, Data: data}); err != nil { return err } if err = closer(); err != nil { return err } os.Remove(cdbName) if len(fnames) == 1 { return os.Rename(fnames[0], cdbName) } bn, ext := nakeFilename(cdbName) if err = os.Rename(fnames[0], bn+".1"+ext); err != nil { return err } return os.Rename(fnames[1], bn+".2"+ext) }
func (n *FileId) String() string { bytes := make([]byte, 12) util.Uint64toBytes(bytes[0:8], n.Key) util.Uint32toBytes(bytes[8:12], n.Hashcode) nonzero_index := 0 for ; bytes[nonzero_index] == 0; nonzero_index++ { } return n.VolumeId.String() + "," + hex.EncodeToString(bytes[nonzero_index:]) }
func (n *Needle) Append(w io.Writer) uint32 { header := make([]byte, 16) util.Uint32toBytes(header[0:4], n.Cookie) util.Uint64toBytes(header[4:12], n.Key) n.Size = uint32(len(n.Data)) util.Uint32toBytes(header[12:16], n.Size) w.Write(header) w.Write(n.Data) rest := 8 - ((n.Size + 16 + 4) % 8) util.Uint32toBytes(header[0:4], uint32(n.Checksum)) w.Write(header[0 : rest+4]) return n.Size }
func (m cdbMap) Get(key uint64) (element *NeedleValue, ok bool) { var ( data []byte k []byte = make([]byte, 8) err error ) util.Uint64toBytes(k, key) if data, err = m.c1.Data(k); err != nil || data == nil { if m.c2 == nil { return nil, false } if data, err = m.c2.Data(k); err != nil || data == nil { return nil, false } } return &NeedleValue{Key: Key(key), Offset: util.BytesToUint32(data[:4]), Size: util.BytesToUint32(data[4:])}, true }
func (n *Needle) Append(w io.Writer, version Version) (size uint32, err error) { if s, ok := w.(io.Seeker); ok { if end, e := s.Seek(0, 1); e == nil { defer func(s io.Seeker, off int64) { if err != nil { if _, e = s.Seek(off, 0); e != nil { fmt.Printf("Failed to seek %s back to %d with error: %s\n", w, off, e) } } }(s, end) } else { err = fmt.Errorf("Cnnot Read Current Volume Position: %s", e) return } } switch version { case Version1: header := make([]byte, NeedleHeaderSize) util.Uint32toBytes(header[0:4], n.Cookie) util.Uint64toBytes(header[4:12], n.Id) n.Size = uint32(len(n.Data)) size = n.Size util.Uint32toBytes(header[12:16], n.Size) if _, err = w.Write(header); err != nil { return } if _, err = w.Write(n.Data); err != nil { return } padding := NeedlePaddingSize - ((NeedleHeaderSize + n.Size + NeedleChecksumSize) % NeedlePaddingSize) util.Uint32toBytes(header[0:NeedleChecksumSize], n.Checksum.Value()) _, err = w.Write(header[0 : NeedleChecksumSize+padding]) return case Version2: header := make([]byte, NeedleHeaderSize) util.Uint32toBytes(header[0:4], n.Cookie) util.Uint64toBytes(header[4:12], n.Id) n.DataSize, n.NameSize, n.MimeSize = uint32(len(n.Data)), uint8(len(n.Name)), uint8(len(n.Mime)) if n.DataSize > 0 { n.Size = 4 + n.DataSize + 1 if n.HasName() { n.Size = n.Size + 1 + uint32(n.NameSize) } if n.HasMime() { n.Size = n.Size + 1 + uint32(n.MimeSize) } } size = n.DataSize util.Uint32toBytes(header[12:16], n.Size) if _, err = w.Write(header); err != nil { return } if n.DataSize > 0 { util.Uint32toBytes(header[0:4], n.DataSize) if _, err = w.Write(header[0:4]); err != nil { return } if _, err = w.Write(n.Data); err != nil { return } util.Uint8toBytes(header[0:1], n.Flags) if _, err = w.Write(header[0:1]); err != nil { return } } if n.HasName() { util.Uint8toBytes(header[0:1], n.NameSize) if _, err = w.Write(header[0:1]); err != nil { return } if _, err = w.Write(n.Name); err != nil { return } } if n.HasMime() { util.Uint8toBytes(header[0:1], n.MimeSize) if _, err = w.Write(header[0:1]); err != nil { return } if _, err = w.Write(n.Mime); err != nil { return } } padding := NeedlePaddingSize - ((NeedleHeaderSize + n.Size + NeedleChecksumSize) % NeedlePaddingSize) util.Uint32toBytes(header[0:NeedleChecksumSize], n.Checksum.Value()) _, err = w.Write(header[0 : NeedleChecksumSize+padding]) return n.DataSize, err } return 0, fmt.Errorf("Unsupported Version! (%d)", version) }