func getPlaylistFromDB(db *levigo.DB) []playListItem { log.Println("Loading Playlist from file...") ro := levigo.NewReadOptions() data, err := db.Get(ro, []byte("playlist")) if err != nil { log.Fatal(err) } p := bytes.NewBuffer(data) dec := gob.NewDecoder(p) var playlist []playListItem //we must decode into a pointer, so we'll take the address of e err = dec.Decode(&playlist) if err != nil { log.Print(err) playlist = []playListItem{} } log.Println("Loaded ", len(playlist), " items into playlist") log.Println(playlist) return playlist }
func AddProc(procID int, db *levigo.DB) error { ro := levigo.NewReadOptions() wo := levigo.NewWriteOptions() data, err := db.Get(ro, []byte("procs")) spdata := bytes.Split(data, []byte(":")) for i, e := range spdata { if string(e) != "" { fmt.Println("ProcID: #", i, string(e)) pid, err := strconv.Atoi(string(e)) if err != nil { return err } if pid == procID { return errors.New("Process already exists") } if isProcAlive(pid) == false { removeProc(pid, db) } } if err != nil { return err } } strdata := string(data) strdata = strdata + ":" + strconv.Itoa(procID) err = db.Put(wo, []byte("procs"), []byte(strdata)) return err }
func loadUsers(db *levigo.DB) map[string]User { log.Println("Loading Users from file...") ro := levigo.NewReadOptions() data, err := db.Get(ro, []byte("Users")) if err != nil { log.Fatal(err) } p := bytes.NewBuffer(data) dec := gob.NewDecoder(p) var users map[string]User //we must decode into a pointer, so we'll take the address of e err = dec.Decode(&users) if err != nil { log.Print(err) users = map[string]User{} } log.Println("Loaded ", len(users), " users") log.Printf("%+v", users) return users }
func (ahr AddHashRequest) Execute(database *levigo.DB, ro *levigo.ReadOptions, wo *levigo.WriteOptions) (*kminvalues.KMinValues, error) { if ahr.Key == "" { return nil, NoKeySpecified } keyBytes := []byte(ahr.Key) data, err := database.Get(ro, keyBytes) if err != nil { return nil, err } kmv, err := kminvalues.KMinValuesFromBytes(data) if err != nil { if len(data) == 0 { kmv = kminvalues.NewKMinValues(*defaultSize) } else { return nil, err } } kmv.AddHash(ahr.Hash) err = database.Put(wo, keyBytes, kmv.Bytes()) return kmv, err }
// Fetch a Tx by hash func GetTx(db *levigo.DB, txHash string) (tx *Tx, err error) { ro := levigo.NewReadOptions() defer ro.Close() txKey, blockErr := db.Get(ro, []byte(fmt.Sprintf("tx!%s", txHash))) if blockErr != nil { err = errors.New("Tx not found") return } txData, blockErr := db.Get(ro, txKey) if blockErr != nil { err = errors.New("Tx not found") return } tx = new(Tx) err = json.Unmarshal(txData, tx) if err != nil { return } for txo_index, txo := range tx.TxOuts { txo.Spent, _ = GetTxoSpent(db, txo.Addr, tx.Hash, txo_index) } return }
// Return the last height processed func GetLastHeight(db *levigo.DB) (lastHeight uint, err error) { ro := levigo.NewReadOptions() defer ro.Close() lastHeightRaw, _ := db.Get(ro, []byte("last-height")) lastHeightInt, _ := strconv.Atoi(string(lastHeightRaw[:])) lastHeight = uint(lastHeightInt) return }
func removeProc(pid int, db *levigo.DB) error { wo := levigo.NewWriteOptions() err := db.Delete(wo, []byte(strconv.Itoa(pid))) if err != nil { return err } return killProc(pid) }
// Write the datastore version to a shard. func writeDataStoreVersion(store *dataStore, ldb *levigo.DB, v uint32) error { w := new(bytes.Buffer) encoder := gob.NewEncoder(w) err := encoder.Encode(&v) if err != nil { return err } return ldb.Put(store.writeOpts, []byte{VERSION_KEY}, w.Bytes()) }
func (sr SetRequest) Execute(database *levigo.DB, ro *levigo.ReadOptions, wo *levigo.WriteOptions) (*KMinValues, error) { if sr.Key == "" { return nil, NoKeySpecified } keyBytes := []byte(sr.Key) err := database.Put(wo, keyBytes, sr.Kmv.Bytes()) return sr.Kmv, err }
func (dr DeleteRequest) Execute(database *levigo.DB, ro *levigo.ReadOptions, wo *levigo.WriteOptions) (*KMinValues, error) { if dr.Key == "" { return nil, NoKeySpecified } keyBytes := []byte(dr.Key) err := database.Delete(wo, keyBytes) return nil, err }
func AddIndex(index [2]string, key []byte, indexDb *levigo.DB, wb *levigo.WriteBatch) error { searchKey := []byte(index[0] + "~" + index[1]) keys, err := indexDb.Get(LReadOptions, searchKey) if err != nil { return err } keys = appendDataKey(keys, key) wb.Put(searchKey, keys) return nil }
/* DelKey deletes key from provided DB handle. */ func DelKey(key string, db *levigo.DB) bool { writer := levigo.NewWriteOptions() defer writer.Close() err := db.Delete(writer, []byte(key)) if err != nil { golerror.Boohoo("Key "+key+" query failed.", false) return false } return true }
/* GetVal gets value of Key from provided db handle. */ func GetVal(key string, db *levigo.DB) string { reader := levigo.NewReadOptions() defer reader.Close() data, err := db.Get(reader, []byte(key)) if err != nil { golerror.Boohoo("Key "+key+" query failed.", false) return "" } return string(data) }
func writeUsersToDB(db *levigo.DB, users map[string]User) { wo := levigo.NewWriteOptions() m := new(bytes.Buffer) enc := gob.NewEncoder(m) enc.Encode(users) err := db.Put(wo, []byte("Users"), m.Bytes()) if err != nil { log.Fatal(err) } wo.Close() }
func writePlaylistToDB(db *levigo.DB, playlist []playListItem) { wo := levigo.NewWriteOptions() m := new(bytes.Buffer) enc := gob.NewEncoder(m) enc.Encode(playlist) err := db.Put(wo, []byte("playlist"), m.Bytes()) if err != nil { log.Fatal(err) } wo.Close() }
/* PushKeyVal push KeyVal in provided DB handle. */ func PushKeyVal(key string, val string, db *levigo.DB) bool { writer := levigo.NewWriteOptions() defer writer.Close() keyname := []byte(key) value := []byte(val) err := db.Put(writer, keyname, value) if err != nil { golerror.Boohoo("Key "+key+" insertion failed. It's value was "+val, false) return false } return true }
func write_data(data []byte, db *levigo.DB, nitems int, keysize int, valsize int) { defer un(trace("write data")) wo := levigo.NewWriteOptions() keystart := 0 valstart := 0 for i := 0; i < nitems; i++ { db.Put(wo, data[keystart:keystart+keysize], data[valstart:valstart+valsize]) keystart %= (len(data) - keysize) valstart %= (len(data) - valsize) } fmt.Println("Wrote ", nitems, "items with key size", keysize, "and value size", valsize) }
func (gr GetRequest) Execute(database *levigo.DB, ro *levigo.ReadOptions, wo *levigo.WriteOptions) (*KMinValues, error) { if gr.Key == "" { return nil, NoKeySpecified } data, err := database.Get(ro, []byte(gr.Key)) if err != nil { return nil, err } // TODO: add error handling in FromBytes kmv := KMinValuesFromBytes(data) return kmv, nil }
// TODO: refactor with above. func RemoveIndex(index [2]string, key []byte, indexDb *levigo.DB, wb *levigo.WriteBatch) error { searchKey := []byte(index[0] + "~" + index[1]) keys, err := indexDb.Get(LReadOptions, searchKey) if err != nil { return err } keys = removeDataKey(keys, key) if len(keys) > 0 { wb.Put(searchKey, keys) } else { wb.Delete(searchKey) } return nil }
// Return block hash in the main chain given the height func GetBlockHashByHeight(db *levigo.DB, blockHeight uint) (hash string, err error) { ro := levigo.NewReadOptions() defer ro.Close() blocks, _ := GetRange(db, []byte(fmt.Sprintf("bl!height!%v!", blockHeight)), []byte(fmt.Sprintf("bl!height!%v!\xff", blockHeight))) for _, bl := range blocks { blStatus, _ := db.Get(ro, []byte(fmt.Sprintf("bl!%v!main", bl.Value))) blStatus2, _ := strconv.Atoi(string(blStatus[:])) if blStatus2 == 1 { hash = bl.Value return } } err = errors.New("Block not found") return }
// Read the datastore version of a leveldb instance. func readLayoutVersion(store *dataStore, ldb *levigo.DB) (uint32, error) { buf, err := ldb.Get(store.readOpts, []byte{VERSION_KEY}) if err != nil { return 0, err } if len(buf) == 0 { return 0, nil } r := bytes.NewBuffer(buf) decoder := gob.NewDecoder(r) var v uint32 err = decoder.Decode(&v) if err != nil { return 0, err } return v, nil }
func (ahr AddHashRequest) Execute(database *levigo.DB, ro *levigo.ReadOptions, wo *levigo.WriteOptions) (*KMinValues, error) { if ahr.Key == "" { return nil, NoKeySpecified } keyBytes := []byte(ahr.Key) data, err := database.Get(ro, keyBytes) if err != nil { return nil, err } kmv := KMinValuesFromBytes(data) kmv.AddHash(ahr.Hash) err = database.Put(wo, keyBytes, kmv.Bytes()) return kmv, err }
func GetSentByAddress(db *levigo.DB, addr string) (total uint, err error) { total = uint(0) ro := levigo.NewReadOptions() defer ro.Close() start := []byte(fmt.Sprintf("%s-txo!", addr)) end := []byte(fmt.Sprintf("%s-txo!\xff", addr)) txos, _ := GetRange(db, start, end) for _, txo := range txos { log.Println(txo.Key) new_key := strings.Replace(txo.Key, "-txo", "-txo-spent", 1) log.Println(new_key) r, _ := db.Get(ro, []byte(new_key)) log.Println(string(r[:])) val, _ := strconv.Atoi(txo.Value) total += uint(val) } return }
// Fetch a single block by hash func GetBlock(db *levigo.DB, blockHash string, fetchTx bool) (block *Block, err error) { ro := levigo.NewReadOptions() defer ro.Close() blockDataRaw, blockErr := db.Get(ro, []byte(fmt.Sprintf("bl!%s", blockHash))) if blockErr != nil { err = errors.New("Block not found") return } //blockStatus, _ := db.Get(ro, []byte(fmt.Sprintf("bl!%v!main", blockHash))) //blockPrv, _ := db.Get(ro, []byte(fmt.Sprintf("bl!%v!prv", blockHash))) if len(blockDataRaw) == 0 { err = errors.New("Block not found") return } block = new(Block) err = json.Unmarshal(blockDataRaw, block) if err != nil { return } if fetchTx { blockNxts, _ := GetRange(db, []byte(fmt.Sprintf("bl!%v!nxt!", block.Hash)), []byte(fmt.Sprintf("bl!%v!nxt!\xff", block.Hash))) for _, nxt := range blockNxts { blStatus, _ := db.Get(ro, []byte(fmt.Sprintf("bl!%v!main", nxt.Value))) blStatus2, _ := strconv.Atoi(string(blStatus[:])) if blStatus2 == 1 { block.Next = nxt.Value } } txs_kv, _ := GetRange(db, []byte(fmt.Sprintf("bl!%v!tx!", block.Hash)), []byte(fmt.Sprintf("bl!%v!tx!\xff", block.Hash))) for _, tx_kv := range txs_kv { tx, _ := GetTxFromKv(tx_kv) block.Txs = append(block.Txs, tx) } } return }
func (gr GetRequest) Execute(database *levigo.DB, ro *levigo.ReadOptions, wo *levigo.WriteOptions) (*kminvalues.KMinValues, error) { if gr.Key == "" { return nil, NoKeySpecified } data, err := database.Get(ro, []byte(gr.Key)) if err != nil { return nil, err } kmv, err := kminvalues.KMinValuesFromBytes(data) if err != nil { if len(data) == 0 { kmv = kminvalues.NewKMinValues(*defaultSize) } else { return nil, err } } return kmv, err }
func ListProcs(db *levigo.DB) (map[int]int, error) { ro := levigo.NewReadOptions() procs, err := db.Get(ro, []byte("procs")) if err != nil { return map[int]int{}, err } procs_arr := strings.Split(string(procs), ":") var procs_arr2 = map[int]int{} for _, p := range procs_arr { status, err := db.Get(ro, []byte("status:"+p)) if err == nil { p_int, _ := strconv.Atoi(p) procs_arr2[p_int], _ = strconv.Atoi(string(status)) } } return procs_arr2, err }
// Timestamp of the block an address was first confirmed in func AddressFirstSeen(db *levigo.DB, addr string) (timestamp uint, err error) { timestamp = uint(0) ro := levigo.NewReadOptions() defer ro.Close() it := db.NewIterator(ro) defer it.Close() it.Seek([]byte(fmt.Sprintf("%s-txo!", addr))) if it.Valid() { k := string(it.Key()[:]) data := strings.Split(k, "!") r, _ := db.Get(ro, []byte(fmt.Sprintf("tx!%s", data[1]))) data = strings.Split(string(r[:]), ":") ts, _ := strconv.Atoi(data[0]) timestamp = uint(ts) return } else { err = errors.New("Address not found") return } }
func NewLevelDbShard(db *levigo.DB) (*LevelDbShard, error) { ro := levigo.NewReadOptions() lastIdBytes, err2 := db.Get(ro, NEXT_ID_KEY) if err2 != nil { return nil, err2 } lastId := uint64(0) if lastIdBytes != nil { lastId, err2 = binary.ReadUvarint(bytes.NewBuffer(lastIdBytes)) if err2 != nil { return nil, err2 } } return &LevelDbShard{ db: db, writeOptions: levigo.NewWriteOptions(), readOptions: ro, lastIdUsed: lastId, }, nil }
func GetRange(db *levigo.DB, kStart []byte, kEnd []byte) (values []*KeyValue, err error) { ro := levigo.NewReadOptions() defer ro.Close() it := db.NewIterator(ro) defer it.Close() it.Seek(kStart) endBytes := kEnd for { if it.Valid() { if bytes.Compare(it.Key(), endBytes) > 0 { return } values = append(values, &KeyValue{string(it.Key()[:]), string(it.Value()[:])}) it.Next() } else { err = it.GetError() return } } return }
func GetTxoSpent(db *levigo.DB, address string, txhhash string, txoindex int) (txospent *TxoSpent, err error) { ro := levigo.NewReadOptions() defer ro.Close() txSpent, err := db.Get(ro, []byte(fmt.Sprintf("%v-txo-spent!%v!%v", address, txhhash, txoindex))) if err != nil { return } txospent = new(TxoSpent) if string(txSpent[:]) == "0" || string(txSpent[:]) == "" { txospent.Spent = false return } txospent.Spent = true txSpentData := strings.Split(string(txSpent[:]), ":") blockHeight, _ := strconv.ParseUint(txSpentData[0], 10, 0) txiIndex, _ := strconv.ParseUint(txSpentData[2], 10, 0) txospent.BlockHeight = uint32(blockHeight) txospent.InputHash = txSpentData[1] txospent.InputIndex = uint32(txiIndex) return }