convert binary Read/Write to Uint/PutUint and copy

This commit is contained in:
David Hill 2014-06-04 14:55:48 -04:00
parent fbb17fd35a
commit e2628dfc0d
3 changed files with 62 additions and 175 deletions

View file

@ -7,7 +7,6 @@ package ldb
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt"
"github.com/conformal/btcdb" "github.com/conformal/btcdb"
"github.com/conformal/btcutil" "github.com/conformal/btcutil"
@ -72,25 +71,17 @@ func (db *LevelDb) FetchBlockHeaderBySha(sha *btcwire.ShaHash) (bh *btcwire.Bloc
} }
func (db *LevelDb) getBlkLoc(sha *btcwire.ShaHash) (int64, error) { func (db *LevelDb) getBlkLoc(sha *btcwire.ShaHash) (int64, error) {
var blkHeight int64
key := shaBlkToKey(sha) key := shaBlkToKey(sha)
data, err := db.lDb.Get(key, db.ro) data, err := db.lDb.Get(key, db.ro)
if err != nil { if err != nil {
return 0, err return 0, err
} }
// deserialize // deserialize
dr := bytes.NewBuffer(data) blkHeight := binary.LittleEndian.Uint64(data)
err = binary.Read(dr, binary.LittleEndian, &blkHeight)
if err != nil { return int64(blkHeight), nil
log.Tracef("get getBlkLoc len %v\n", len(data))
err = fmt.Errorf("Db Corrupt 0")
return 0, err
}
return blkHeight, nil
} }
func (db *LevelDb) getBlkByHeight(blkHeight int64) (rsha *btcwire.ShaHash, rbuf []byte, err error) { func (db *LevelDb) getBlkByHeight(blkHeight int64) (rsha *btcwire.ShaHash, rbuf []byte, err error) {
@ -131,17 +122,12 @@ func (db *LevelDb) getBlk(sha *btcwire.ShaHash) (rblkHeight int64, rbuf []byte,
return blkHeight, buf, nil return blkHeight, buf, nil
} }
func (db *LevelDb) setBlk(sha *btcwire.ShaHash, blkHeight int64, buf []byte) error { func (db *LevelDb) setBlk(sha *btcwire.ShaHash, blkHeight int64, buf []byte) {
// serialize // serialize
var lw bytes.Buffer var lw [8]byte
err := binary.Write(&lw, binary.LittleEndian, blkHeight) binary.LittleEndian.PutUint64(lw[:], uint64(blkHeight))
if err != nil {
err = fmt.Errorf("Write Fail")
return err
}
shaKey := shaBlkToKey(sha)
shaKey := shaBlkToKey(sha)
blkKey := int64ToKey(blkHeight) blkKey := int64ToKey(blkHeight)
shaB := sha.Bytes() shaB := sha.Bytes()
@ -149,21 +135,15 @@ func (db *LevelDb) setBlk(sha *btcwire.ShaHash, blkHeight int64, buf []byte) err
copy(blkVal[0:], shaB) copy(blkVal[0:], shaB)
copy(blkVal[len(shaB):], buf) copy(blkVal[len(shaB):], buf)
db.lBatch().Put(shaKey, lw.Bytes()) db.lBatch().Put(shaKey, lw[:])
db.lBatch().Put(blkKey, blkVal) db.lBatch().Put(blkKey, blkVal)
return nil
} }
// insertSha stores a block hash and its associated data block with a // insertSha stores a block hash and its associated data block with a
// previous sha of `prevSha'. // previous sha of `prevSha'.
// insertSha shall be called with db lock held // insertSha shall be called with db lock held
func (db *LevelDb) insertBlockData(sha *btcwire.ShaHash, prevSha *btcwire.ShaHash, buf []byte) (blockid int64, err error) { func (db *LevelDb) insertBlockData(sha *btcwire.ShaHash, prevSha *btcwire.ShaHash, buf []byte) (int64, error) {
oBlkHeight, err := db.getBlkLoc(prevSha)
var oBlkHeight int64
oBlkHeight, err = db.getBlkLoc(prevSha)
if err != nil { if err != nil {
// check current block count // check current block count
// if count != 0 { // if count != 0 {
@ -179,11 +159,7 @@ func (db *LevelDb) insertBlockData(sha *btcwire.ShaHash, prevSha *btcwire.ShaHas
// TODO(drahn) check curfile filesize, increment curfile if this puts it over // TODO(drahn) check curfile filesize, increment curfile if this puts it over
blkHeight := oBlkHeight + 1 blkHeight := oBlkHeight + 1
err = db.setBlk(sha, blkHeight, buf) db.setBlk(sha, blkHeight, buf)
if err != nil {
return
}
// update the last block cache // update the last block cache
db.lastBlkShaCached = true db.lastBlkShaCached = true

View file

@ -649,28 +649,22 @@ func (db *LevelDb) processBatches() error {
for txSha, txU := range db.txUpdateMap { for txSha, txU := range db.txUpdateMap {
key := shaTxToKey(&txSha) key := shaTxToKey(&txSha)
if txU.delete { if txU.delete {
//log.Infof("deleting tx %v", txSha) log.Tracef("deleting tx %v", txSha)
db.lbatch.Delete(key) db.lbatch.Delete(key)
} else { } else {
//log.Infof("inserting tx %v", txSha) log.Tracef("inserting tx %v", txSha)
txdat, err := db.formatTx(txU) txdat := db.formatTx(txU)
if err != nil {
return err
}
db.lbatch.Put(key, txdat) db.lbatch.Put(key, txdat)
} }
} }
for txSha, txSu := range db.txSpentUpdateMap { for txSha, txSu := range db.txSpentUpdateMap {
key := shaSpentTxToKey(&txSha) key := shaSpentTxToKey(&txSha)
if txSu.delete { if txSu.delete {
//log.Infof("deleting tx %v", txSha) log.Tracef("deleting tx %v", txSha)
db.lbatch.Delete(key) db.lbatch.Delete(key)
} else { } else {
//log.Infof("inserting tx %v", txSha) log.Tracef("inserting tx %v", txSha)
txdat, err := db.formatTxFullySpent(txSu.txl) txdat := db.formatTxFullySpent(txSu.txl)
if err != nil {
return err
}
db.lbatch.Put(key, txdat) db.lbatch.Put(key, txdat)
} }
} }

173
ldb/tx.go
View file

@ -7,7 +7,6 @@ package ldb
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt"
"github.com/conformal/btcdb" "github.com/conformal/btcdb"
"github.com/conformal/btcwire" "github.com/conformal/btcwire"
@ -61,81 +60,36 @@ func (db *LevelDb) insertTx(txSha *btcwire.ShaHash, height int64, txoff int, txl
} }
// formatTx generates the value buffer for the Tx db. // formatTx generates the value buffer for the Tx db.
func (db *LevelDb) formatTx(txu *txUpdateObj) ([]byte, error) { func (db *LevelDb) formatTx(txu *txUpdateObj) []byte {
blkHeight := uint64(txu.blkHeight)
blkHeight := txu.blkHeight txOff := uint32(txu.txoff)
txoff := txu.txoff txLen := uint32(txu.txlen)
txlen := txu.txlen
spentbuf := txu.spentData spentbuf := txu.spentData
txOff := int32(txoff) txW := make([]byte, 16+len(spentbuf))
txLen := int32(txlen) binary.LittleEndian.PutUint64(txW[:], blkHeight)
binary.LittleEndian.PutUint32(txW[8:], txOff)
binary.LittleEndian.PutUint32(txW[12:], txLen)
copy(txW[16:], spentbuf)
var txW bytes.Buffer return txW[:]
err := binary.Write(&txW, binary.LittleEndian, blkHeight)
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
err = binary.Write(&txW, binary.LittleEndian, txOff)
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
err = binary.Write(&txW, binary.LittleEndian, txLen)
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
err = binary.Write(&txW, binary.LittleEndian, spentbuf)
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
return txW.Bytes(), nil
} }
func (db *LevelDb) getTxData(txsha *btcwire.ShaHash) (rblkHeight int64, func (db *LevelDb) getTxData(txsha *btcwire.ShaHash) (int64, int, int, []byte, error) {
rtxOff int, rtxLen int, rspentBuf []byte, err error) {
var buf []byte
key := shaTxToKey(txsha) key := shaTxToKey(txsha)
buf, err = db.lDb.Get(key, db.ro) buf, err := db.lDb.Get(key, db.ro)
if err != nil { if err != nil {
return return 0, 0, 0, nil, err
} }
var blkHeight int64 blkHeight := binary.LittleEndian.Uint64(buf)
var txOff, txLen int32 txOff := binary.LittleEndian.Uint32(buf[8:])
dr := bytes.NewBuffer(buf) txLen := binary.LittleEndian.Uint32(buf[12:])
err = binary.Read(dr, binary.LittleEndian, &blkHeight)
if err != nil { spentBuf := make([]byte, len(buf)-16)
err = fmt.Errorf("Db Corrupt 1") copy(spentBuf, buf[16:])
return
} return int64(blkHeight), int(txOff), int(txLen), spentBuf, nil
err = binary.Read(dr, binary.LittleEndian, &txOff)
if err != nil {
err = fmt.Errorf("Db Corrupt 2")
return
}
err = binary.Read(dr, binary.LittleEndian, &txLen)
if err != nil {
err = fmt.Errorf("Db Corrupt 3")
return
}
// remainder of buffer is spentbuf
spentBuf := make([]byte, dr.Len())
err = binary.Read(dr, binary.LittleEndian, spentBuf)
if err != nil {
err = fmt.Errorf("Db Corrupt 4")
return
}
return blkHeight, int(txOff), int(txLen), spentBuf, nil
} }
func (db *LevelDb) getTxFullySpent(txsha *btcwire.ShaHash) ([]*spentTx, error) { func (db *LevelDb) getTxFullySpent(txsha *btcwire.ShaHash) ([]*spentTx, error) {
@ -150,41 +104,22 @@ func (db *LevelDb) getTxFullySpent(txsha *btcwire.ShaHash) ([]*spentTx, error) {
return badTxList, err return badTxList, err
} }
txListLen := len(buf) / 20 txListLen := len(buf) / 20
txR := bytes.NewBuffer(buf)
spentTxList = make([]*spentTx, txListLen, txListLen) spentTxList = make([]*spentTx, txListLen, txListLen)
for i := range spentTxList { for i := range spentTxList {
var sTx spentTx offset := i * 20
var blkHeight int64
var txOff, txLen, numTxO int32
err := binary.Read(txR, binary.LittleEndian, &blkHeight) blkHeight := binary.LittleEndian.Uint64(buf[offset:])
if err != nil { txOff := binary.LittleEndian.Uint32(buf[offset+8:])
err = fmt.Errorf("sTx Read fail 0") txLen := binary.LittleEndian.Uint32(buf[offset+12:])
return nil, err numTxO := binary.LittleEndian.Uint32(buf[offset+16:])
}
sTx.blkHeight = blkHeight
err = binary.Read(txR, binary.LittleEndian, &txOff) sTx := spentTx{
if err != nil { blkHeight: int64(blkHeight),
err = fmt.Errorf("sTx Read fail 1") txoff: int(txOff),
return nil, err txlen: int(txLen),
numTxO: int(numTxO),
} }
sTx.txoff = int(txOff)
err = binary.Read(txR, binary.LittleEndian, &txLen)
if err != nil {
err = fmt.Errorf("sTx Read fail 2")
return nil, err
}
sTx.txlen = int(txLen)
err = binary.Read(txR, binary.LittleEndian, &numTxO)
if err != nil {
err = fmt.Errorf("sTx Read fail 3")
return nil, err
}
sTx.numTxO = int(numTxO)
spentTxList[i] = &sTx spentTxList[i] = &sTx
} }
@ -192,41 +127,23 @@ func (db *LevelDb) getTxFullySpent(txsha *btcwire.ShaHash) ([]*spentTx, error) {
return spentTxList, nil return spentTxList, nil
} }
func (db *LevelDb) formatTxFullySpent(sTxList []*spentTx) ([]byte, error) { func (db *LevelDb) formatTxFullySpent(sTxList []*spentTx) []byte {
var txW bytes.Buffer txW := make([]byte, 20*len(sTxList))
for _, sTx := range sTxList { for i, sTx := range sTxList {
blkHeight := sTx.blkHeight blkHeight := uint64(sTx.blkHeight)
txOff := int32(sTx.txoff) txOff := uint32(sTx.txoff)
txLen := int32(sTx.txlen) txLen := uint32(sTx.txlen)
numTxO := int32(sTx.numTxO) numTxO := uint32(sTx.numTxO)
offset := i * 20
err := binary.Write(&txW, binary.LittleEndian, blkHeight) binary.LittleEndian.PutUint64(txW[offset:], blkHeight)
if err != nil { binary.LittleEndian.PutUint32(txW[offset+8:], txOff)
err = fmt.Errorf("Write fail") binary.LittleEndian.PutUint32(txW[offset+12:], txLen)
return nil, err binary.LittleEndian.PutUint32(txW[offset+16:], numTxO)
} }
err = binary.Write(&txW, binary.LittleEndian, txOff) return txW
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
err = binary.Write(&txW, binary.LittleEndian, txLen)
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
err = binary.Write(&txW, binary.LittleEndian, numTxO)
if err != nil {
err = fmt.Errorf("Write fail")
return nil, err
}
}
return txW.Bytes(), nil
} }
// ExistsTxSha returns if the given tx sha exists in the database // ExistsTxSha returns if the given tx sha exists in the database