本文整理汇总了Golang中github.com/conformal/btcdb.CreateDB函数的典型用法代码示例。如果您正苦于以下问题:Golang CreateDB函数的具体用法?Golang CreateDB怎么用?Golang CreateDB使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CreateDB函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: createDB
// createDB creates a new db instance and returns a teardown function the caller
// should invoke when done testing to clean up. The close flag indicates
// whether or not the teardown function should sync and close the database
// during teardown.
func createDB(dbType, dbName string, close bool) (btcdb.Db, func(), error) {
// Handle memory database specially since it doesn't need the disk
// specific handling.
if dbType == "memdb" {
db, err := btcdb.CreateDB(dbType)
if err != nil {
return nil, nil, fmt.Errorf("error creating db: %v", err)
}
// Setup a teardown function for cleaning up. This function is
// returned to the caller to be invoked when it is done testing.
teardown := func() {
if close {
db.Close()
}
}
return db, teardown, nil
}
// Create the root directory for test databases.
if !fileExists(testDbRoot) {
if err := os.MkdirAll(testDbRoot, 0700); err != nil {
err := fmt.Errorf("unable to create test db "+
"root: %v", err)
return nil, nil, err
}
}
// Create a new database to store the accepted blocks into.
dbPath := filepath.Join(testDbRoot, dbName)
_ = os.RemoveAll(dbPath)
db, err := btcdb.CreateDB(dbType, dbPath)
if err != nil {
return nil, nil, fmt.Errorf("error creating db: %v", err)
}
// Setup a teardown function for cleaning up. This function is
// returned to the caller to be invoked when it is done testing.
teardown := func() {
dbVersionPath := filepath.Join(testDbRoot, dbName+".ver")
if close {
db.Sync()
db.Close()
}
os.RemoveAll(dbPath)
os.Remove(dbVersionPath)
os.RemoveAll(testDbRoot)
}
return db, teardown, nil
}
示例2: ExampleCreateDB
// This example demonstrates creating a new database and inserting the genesis
// block into it.
func ExampleCreateDB() {
// Notice in these example imports that the memdb driver is loaded.
// Ordinarily this would be whatever driver(s) your application
// requires.
// import (
// "github.com/conformal/btcdb"
// _ "github.com/conformal/btcdb/memdb"
// )
// Create a database and schedule it to be closed on exit. This example
// uses a memory-only database to avoid needing to write anything to
// the disk. Typically, you would specify a persistent database driver
// such as "leveldb" and give it a database name as the second
// parameter.
db, err := btcdb.CreateDB("memdb")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
// Insert the main network genesis block.
genesis := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock)
newHeight, err := db.InsertBlock(genesis)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("New height:", newHeight)
// Output:
// New height: 0
}
示例3: setupBlockDB
// setupBlockDB loads (or creates when needed) the block database taking into
// account the selected database backend. It also contains additional logic
// such warning the user if there are multiple databases which consume space on
// the file system and ensuring the regression test database is clean when in
// regression test mode.
func setupBlockDB() (btcdb.Db, error) {
// The memdb backend does not have a file path associated with it, so
// handle it uniquely. We also don't want to worry about the multiple
// database type warnings when running with the memory database.
if cfg.DbType == "memdb" {
btcdLog.Infof("Creating block database in memory.")
db, err := btcdb.CreateDB(cfg.DbType)
if err != nil {
return nil, err
}
return db, nil
}
warnMultipeDBs()
// The database name is based on the database type.
dbPath := blockDbPath(cfg.DbType)
// The regression test is special in that it needs a clean database for
// each run, so remove it now if it already exists.
removeRegressionDB(dbPath)
btcdLog.Infof("Loading block database from '%s'", dbPath)
db, err := btcdb.OpenDB(cfg.DbType, dbPath)
if err != nil {
// Return the error if it's not because the database
// doesn't exist.
if err != btcdb.DbDoesNotExist {
return nil, err
}
// Create the db if it does not exist.
err = os.MkdirAll(cfg.DataDir, 0700)
if err != nil {
return nil, err
}
db, err = btcdb.CreateDB(cfg.DbType, dbPath)
if err != nil {
return nil, err
}
}
return db, nil
}
示例4: loadBlockDB
// loadBlockDB opens the block database and returns a handle to it.
func loadBlockDB() (btcdb.Db, error) {
// The database name is based on the database type.
dbName := blockDbNamePrefix + "_" + cfg.DbType
if cfg.DbType == "sqlite" {
dbName = dbName + ".db"
}
dbPath := filepath.Join(cfg.DataDir, dbName)
// The regression test is special in that it needs a clean database for
// each run, so remove it now if it already exists.
removeRegressionDB(dbPath)
log.Infof("[BMGR] Loading block database from '%s'", dbPath)
db, err := btcdb.OpenDB(cfg.DbType, dbPath)
if err != nil {
// Return the error if it's not because the database doesn't
// exist.
if err != btcdb.DbDoesNotExist {
return nil, err
}
// Create the db if it does not exist.
err = os.MkdirAll(cfg.DataDir, 0700)
if err != nil {
return nil, err
}
db, err = btcdb.CreateDB(cfg.DbType, dbPath)
if err != nil {
return nil, err
}
}
// Get the latest block height from the database.
_, height, err := db.NewestSha()
if err != nil {
db.Close()
return nil, err
}
// Insert the appropriate genesis block for the bitcoin network being
// connected to if needed.
if height == -1 {
genesis := btcutil.NewBlock(activeNetParams.genesisBlock)
_, err := db.InsertBlock(genesis)
if err != nil {
db.Close()
return nil, err
}
log.Infof("[BMGR] Inserted genesis block %v",
activeNetParams.genesisHash)
height = 0
}
log.Infof("[BMGR] Block database loaded with block height %d", height)
return db, nil
}
示例5: exampleLoadDB
// exampleLoadDB is used in the example to elide the setup code.
func exampleLoadDB() (btcdb.Db, error) {
db, err := btcdb.CreateDB("memdb")
if err != nil {
return nil, err
}
// Insert the main network genesis block.
genesis := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock)
_, err = db.InsertBlock(genesis)
if err != nil {
return nil, err
}
return db, err
}
示例6: TestBdb
func TestBdb(t *testing.T) {
// Ignore db remove errors since it means we didn't have an old one.
_ = os.Remove("tstdb1")
db, err := btcdb.CreateDB("sqlite", "tstdb1")
if err != nil {
t.Errorf("Failed to open test database %v", err)
return
}
defer os.Remove("tstdb1")
for i := range testShas {
var previous btcwire.ShaHash
if i == 0 {
previous = btcwire.GenesisHash
} else {
previous = testShas[i-1]
}
_, err := db.InsertBlockData(&testShas[i], &previous, 1, zeroBlock)
if err != nil {
t.Errorf("Failed to insert testSha %d. Error: %v",
i, err)
return
}
testFetch(t, db, testShas[0:i+1], "pre sync ")
}
// XXX insert enough so that we hit the transaction limit
// XXX try and insert a with a bad previous
db.Sync()
testFetch(t, db, testShas, "post sync")
for i := len(testShas) - 1; i >= 0; i-- {
err := db.DropAfterBlockBySha(testShas[i])
if err != nil {
t.Errorf("drop after %d failed %v", i, err)
break
}
testFetch(t, db, testShas[:i+1],
fmt.Sprintf("post DropAfter for sha %d", i))
}
// Just tests that it doesn't crash, no return value
db.Close()
}
示例7: TestEmptyDB
func TestEmptyDB(t *testing.T) {
dbname := "tstdbempty"
dbnamever := dbname + ".ver"
_ = os.RemoveAll(dbname)
_ = os.RemoveAll(dbnamever)
db, err := btcdb.CreateDB("leveldb", dbname)
if err != nil {
t.Errorf("Failed to open test database %v", err)
return
}
defer os.RemoveAll(dbname)
defer os.RemoveAll(dbnamever)
sha, height, err := db.NewestSha()
if !sha.IsEqual(&btcwire.ShaHash{}) {
t.Errorf("sha not zero hash")
}
if height != -1 {
t.Errorf("height not -1 %v", height)
}
// This is a reopen test
if err := db.Close(); err != nil {
t.Errorf("Close: unexpected error: %v", err)
}
db, err = btcdb.OpenDB("leveldb", dbname)
if err != nil {
t.Errorf("Failed to open test database %v", err)
return
}
defer func() {
if err := db.Close(); err != nil {
t.Errorf("Close: unexpected error: %v", err)
}
}()
sha, height, err = db.NewestSha()
if !sha.IsEqual(&btcwire.ShaHash{}) {
t.Errorf("sha not zero hash")
}
if height != -1 {
t.Errorf("height not -1 %v", height)
}
}
示例8: TestCreateOpenUnsupported
// TestCreateOpenUnsupported ensures that attempting to create or open an
// unsupported database type is handled properly.
func TestCreateOpenUnsupported(t *testing.T) {
// Ensure creating a database with an unsupported type fails with the
// expected error.
dbType := "unsupported"
_, err := btcdb.CreateDB(dbType, "unsupportedcreatetest")
if err != btcdb.ErrDbUnknownType {
t.Errorf("TestCreateOpenUnsupported: expected error not "+
"received - got: %v, want %v", err, btcdb.ErrDbUnknownType)
return
}
// Ensure opening a database with the new type fails with the expected
// error.
_, err = btcdb.OpenDB(dbType, "unsupportedopentest")
if err != btcdb.ErrDbUnknownType {
t.Errorf("TestCreateOpenUnsupported: expected error not "+
"received - got: %v, want %v", err, btcdb.ErrDbUnknownType)
return
}
}
示例9: ExampleBlockChain_ProcessBlock
// This example demonstrates how to create a new chain instance and use
// ProcessBlock to attempt to attempt add a block to the chain. As the package
// overview documentation describes, this includes all of the Bitcoin consensus
// rules. This example intentionally attempts to insert a duplicate genesis
// block to illustrate how an invalid block is handled.
func ExampleBlockChain_ProcessBlock() {
// Create a new database to store the accepted blocks into. Typically
// this would be opening an existing database and would not use memdb
// which is a memory-only database backend, but we create a new db
// here so this is a complete working example.
db, err := btcdb.CreateDB("memdb")
if err != nil {
fmt.Printf("Failed to create database: %v\n", err)
return
}
defer db.Close()
// Insert the main network genesis block. This is part of the initial
// database setup. Like above, this typically would not be needed when
// opening an existing database.
genesisBlock := btcutil.NewBlock(btcnet.MainNetParams.GenesisBlock)
_, err = db.InsertBlock(genesisBlock)
if err != nil {
fmt.Printf("Failed to insert genesis block: %v\n", err)
return
}
// Create a new BlockChain instance using the underlying database for
// the main bitcoin network and ignore notifications.
chain := btcchain.New(db, &btcnet.MainNetParams, nil)
// Process a block. For this example, we are going to intentionally
// cause an error by trying to process the genesis block which already
// exists.
isOrphan, err := chain.ProcessBlock(genesisBlock, btcchain.BFNone)
if err != nil {
fmt.Printf("Failed to process block: %v\n", err)
return
}
fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
// Output:
// Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
}
示例10: TestCreateOpenFail
// TestCreateOpenFail ensures that errors which occur while opening or closing
// a database are handled properly.
func TestCreateOpenFail(t *testing.T) {
// bogusCreateDB is a function which acts as a bogus create and open
// driver function that intentionally returns a failure which can be
// detected.
dbType := "createopenfail"
openError := fmt.Errorf("failed to create or open database for "+
"database type [%v]", dbType)
bogusCreateDB := func(args ...interface{}) (btcdb.Db, error) {
return nil, openError
}
// Create and add driver that intentionally fails when created or opened
// to ensure errors on database open and create are handled properly.
driver := btcdb.DriverDB{
DbType: dbType,
CreateDB: bogusCreateDB,
OpenDB: bogusCreateDB,
}
btcdb.AddDBDriver(driver)
// Ensure creating a database with the new type fails with the expected
// error.
_, err := btcdb.CreateDB(dbType, "createfailtest")
if err != openError {
t.Errorf("TestCreateOpenFail: expected error not received - "+
"got: %v, want %v", err, openError)
return
}
// Ensure opening a database with the new type fails with the expected
// error.
_, err = btcdb.OpenDB(dbType, "openfailtest")
if err != openError {
t.Errorf("TestCreateOpenFail: expected error not received - "+
"got: %v, want %v", err, openError)
return
}
}
示例11: loadBlockDB
// loadBlockDB opens the block database and returns a handle to it.
func loadBlockDB() (btcdb.Db, error) {
// The database name is based on the database type.
dbName := blockDbNamePrefix + "_" + cfg.DbType
if cfg.DbType == "sqlite" {
dbName = dbName + ".db"
}
dbPath := filepath.Join(cfg.DataDir, dbName)
log.Infof("Loading block database from '%s'", dbPath)
db, err := btcdb.OpenDB(cfg.DbType, dbPath)
if err != nil {
// Return the error if it's not because the database doesn't
// exist.
if err != btcdb.ErrDbDoesNotExist {
return nil, err
}
// Create the db if it does not exist.
err = os.MkdirAll(cfg.DataDir, 0700)
if err != nil {
return nil, err
}
db, err = btcdb.CreateDB(cfg.DbType, dbPath)
if err != nil {
return nil, err
}
}
// Get the latest block height from the database.
_, height, err := db.NewestSha()
if err != nil {
db.Close()
return nil, err
}
log.Infof("Block database loaded with block height %d", height)
return db, nil
}
示例12: chainSetup
// chainSetup is used to create a new db and chain instance with the genesis
// block already inserted. In addition to the new chain instnce, it returns
// a teardown function the caller should invoke when done testing to clean up.
func chainSetup(dbName string) (*btcchain.BlockChain, func(), error) {
if !isSupportedDbType(testDbType) {
return nil, nil, fmt.Errorf("unsupported db type %v", testDbType)
}
// Handle memory database specially since it doesn't need the disk
// specific handling.
var db btcdb.Db
var teardown func()
if testDbType == "memdb" {
ndb, err := btcdb.CreateDB(testDbType)
if err != nil {
return nil, nil, fmt.Errorf("error creating db: %v", err)
}
db = ndb
// Setup a teardown function for cleaning up. This function is
// returned to the caller to be invoked when it is done testing.
teardown = func() {
db.Close()
}
} else {
// Create the root directory for test databases.
if !fileExists(testDbRoot) {
if err := os.MkdirAll(testDbRoot, 0700); err != nil {
err := fmt.Errorf("unable to create test db "+
"root: %v", err)
return nil, nil, err
}
}
// Create a new database to store the accepted blocks into.
dbPath := filepath.Join(testDbRoot, dbName)
_ = os.RemoveAll(dbPath)
ndb, err := btcdb.CreateDB(testDbType, dbPath)
if err != nil {
return nil, nil, fmt.Errorf("error creating db: %v", err)
}
db = ndb
// Setup a teardown function for cleaning up. This function is
// returned to the caller to be invoked when it is done testing.
teardown = func() {
dbVersionPath := filepath.Join(testDbRoot, dbName+".ver")
db.Sync()
db.Close()
os.RemoveAll(dbPath)
os.Remove(dbVersionPath)
os.RemoveAll(testDbRoot)
}
}
// Insert the main network genesis block. This is part of the initial
// database setup.
genesisBlock := btcutil.NewBlock(&btcwire.GenesisBlock)
_, err := db.InsertBlock(genesisBlock)
if err != nil {
teardown()
err := fmt.Errorf("failed to insert genesis block: %v", err)
return nil, nil, err
}
chain := btcchain.New(db, btcwire.MainNet, nil)
return chain, teardown, nil
}
示例13: testBackout
func testBackout(t *testing.T, mode int) {
// simplified basic operation is:
// 1) fetch block from remote server
// 2) look up all txin (except coinbase in db)
// 3) insert block
// Ignore db remove errors since it means we didn't have an old one.
dbname := "tstdbop2"
_ = os.Remove(dbname)
db, err := btcdb.CreateDB("sqlite", dbname)
if err != nil {
t.Errorf("Failed to open test database %v", err)
return
}
defer os.Remove(dbname)
defer db.Close()
switch mode {
case dbTmDefault: // default
// no setup
case dbTmNormal: // explicit normal
db.SetDBInsertMode(btcdb.InsertNormal)
case dbTmFast: // fast mode
db.SetDBInsertMode(btcdb.InsertFast)
if sqldb, ok := db.(*sqlite3.SqliteDb); ok {
sqldb.TempTblMax = 100
} else {
t.Errorf("not right type")
}
}
// Since we are dealing with small dataset, reduce cache size
sqlite3.SetBlockCacheSize(db, 2)
sqlite3.SetTxCacheSize(db, 3)
testdatafile := filepath.Join("testdata", "blocks1-256.bz2")
blocks, err := loadBlocks(t, testdatafile)
if len(blocks) < 120 {
t.Errorf("test data too small")
return
}
err = nil
for height := int64(1); height < int64(len(blocks)); height++ {
if height == 100 {
t.Logf("Syncing at block height 100")
db.Sync()
}
if height == 120 {
t.Logf("Simulating unexpected application quit")
// Simulate unexpected application quit
db.RollbackClose()
break
}
block := blocks[height]
newheight, err := db.InsertBlock(block)
if err != nil {
t.Errorf("failed to insert block %v err %v", height, err)
break
}
if newheight != height {
t.Errorf("height mismatch expect %v returned %v", height, newheight)
break
}
}
// db was closed at height 120, so no cleanup is possible.
// reopen db
db, err = btcdb.OpenDB("sqlite", dbname)
if err != nil {
t.Errorf("Failed to open test database %v", err)
return
}
defer db.Close()
sha, err := blocks[99].Sha()
if err != nil {
t.Errorf("failed to get block 99 sha err %v", err)
return
}
_ = db.ExistsSha(sha)
_, err = db.FetchBlockBySha(sha)
if err != nil {
t.Errorf("failed to load block 99 from db", err)
}
sha, err = blocks[110].Sha()
if err != nil {
t.Errorf("failed to get block 110 sha err %v", err)
return
}
_ = db.ExistsSha(sha)
_, err = db.FetchBlockBySha(sha)
if err == nil {
t.Errorf("loaded block 110 from db, failure expected")
return
}
//.........这里部分代码省略.........
示例14: testUnspentInsert
// insert every block in the test chain
// after each insert, fetch all the tx affected by the latest
// block and verify that the the tx is spent/unspent
// new tx should be fully unspent, referenced tx should have
// the associated txout set to spent.
func testUnspentInsert(t *testing.T) {
// Ignore db remove errors since it means we didn't have an old one.
dbname := fmt.Sprintf("tstdbuspnt1")
dbnamever := dbname + ".ver"
_ = os.RemoveAll(dbname)
_ = os.RemoveAll(dbnamever)
db, err := btcdb.CreateDB("leveldb", dbname)
if err != nil {
t.Errorf("Failed to open test database %v", err)
return
}
defer os.RemoveAll(dbname)
defer os.RemoveAll(dbnamever)
defer db.Close()
blocks := loadblocks(t)
endtest:
for height := int64(0); height < int64(len(blocks)); height++ {
block := blocks[height]
// look up inputs to this x
mblock := block.MsgBlock()
var txneededList []*btcwire.ShaHash
var txlookupList []*btcwire.ShaHash
var txOutList []*btcwire.ShaHash
var txInList []*btcwire.OutPoint
for _, tx := range mblock.Transactions {
for _, txin := range tx.TxIn {
if txin.PreviousOutpoint.Index == uint32(4294967295) {
continue
}
origintxsha := &txin.PreviousOutpoint.Hash
txInList = append(txInList, &txin.PreviousOutpoint)
txneededList = append(txneededList, origintxsha)
txlookupList = append(txlookupList, origintxsha)
if !db.ExistsTxSha(origintxsha) {
t.Errorf("referenced tx not found %v ", origintxsha)
}
}
txshaname, _ := tx.TxSha()
txlookupList = append(txlookupList, &txshaname)
txOutList = append(txOutList, &txshaname)
}
txneededmap := map[btcwire.ShaHash]*btcdb.TxListReply{}
txlist := db.FetchUnSpentTxByShaList(txneededList)
for _, txe := range txlist {
if txe.Err != nil {
t.Errorf("tx list fetch failed %v err %v ", txe.Sha, txe.Err)
break endtest
}
txneededmap[*txe.Sha] = txe
}
for _, spend := range txInList {
itxe := txneededmap[spend.Hash]
if itxe.TxSpent[spend.Index] == true {
t.Errorf("txin %v:%v is already spent", spend.Hash, spend.Index)
}
}
newheight, err := db.InsertBlock(block)
if err != nil {
t.Errorf("failed to insert block %v err %v", height, err)
break endtest
}
if newheight != height {
t.Errorf("height mismatch expect %v returned %v", height, newheight)
break endtest
}
txlookupmap := map[btcwire.ShaHash]*btcdb.TxListReply{}
txlist = db.FetchTxByShaList(txlookupList)
for _, txe := range txlist {
if txe.Err != nil {
t.Errorf("tx list fetch failed %v err %v ", txe.Sha, txe.Err)
break endtest
}
txlookupmap[*txe.Sha] = txe
}
for _, spend := range txInList {
itxe := txlookupmap[spend.Hash]
if itxe.TxSpent[spend.Index] == false {
t.Errorf("txin %v:%v is unspent %v", spend.Hash, spend.Index, itxe.TxSpent)
}
}
for _, txo := range txOutList {
itxe := txlookupmap[*txo]
for i, spent := range itxe.TxSpent {
if spent == true {
t.Errorf("freshly inserted tx %v already spent %v", txo, i)
}
}
//.........这里部分代码省略.........
示例15: main
func main() {
cfg := config{
DbType: "leveldb",
DataDir: filepath.Join(btcdHomeDir(), "data"),
}
parser := flags.NewParser(&cfg, flags.Default)
_, err := parser.Parse()
if err != nil {
if e, ok := err.(*flags.Error); !ok || e.Type != flags.ErrHelp {
parser.WriteHelp(os.Stderr)
}
return
}
runtime.GOMAXPROCS(runtime.NumCPU())
log, err = seelog.LoggerFromWriterWithMinLevel(os.Stdout,
seelog.InfoLvl)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create logger: %v", err)
return
}
defer log.Flush()
btcdb.UseLogger(log)
var testnet string
if cfg.TestNet3 {
testnet = "testnet"
} else {
testnet = "mainnet"
}
cfg.DataDir = filepath.Join(cfg.DataDir, testnet)
err = os.MkdirAll(cfg.DataDir, 0700)
if err != nil {
fmt.Printf("unable to create db repo area %v, %v", cfg.DataDir, err)
}
blockDbNamePrefix := "blocks"
dbName := blockDbNamePrefix + "_" + cfg.DbType
if cfg.DbType == "sqlite" {
dbName = dbName + ".db"
}
dbPath := filepath.Join(cfg.DataDir, dbName)
log.Infof("loading db")
db, err := btcdb.CreateDB(cfg.DbType, dbPath)
if err != nil {
log.Warnf("db open failed: %v", err)
return
}
defer db.Close()
log.Infof("db created")
var fi io.ReadCloser
fi, err = os.Open(cfg.InFile)
if err != nil {
log.Warnf("failed to open file %v, err %v", cfg.InFile, err)
}
defer func() {
if err := fi.Close(); err != nil {
log.Warn("failed to close file %v %v", cfg.InFile, err)
}
}()
bufqueue := make(chan *bufQueue, 2)
blkqueue := make(chan *blkQueue, 2)
for i := 0; i < runtime.NumCPU(); i++ {
go processBuf(i, bufqueue, blkqueue)
}
go processBuf(0, bufqueue, blkqueue)
go readBlocks(fi, bufqueue)
var eheight int64
doneMap := map[int64]*blkQueue{}
for {
select {
case blkM := <-blkqueue:
doneMap[blkM.height] = blkM
for {
if blkP, ok := doneMap[eheight]; ok {
delete(doneMap, eheight)
blkP.complete <- true
db.InsertBlock(blkP.blk)
if cfg.Progress && eheight%int64(1) == 0 {
log.Infof("Processing block %v", eheight)
}
eheight++
if eheight%2000 == 0 {
f, err := os.Create(fmt.Sprintf("profile.%d", eheight))
if err == nil {
pprof.WriteHeapProfile(f)
//.........这里部分代码省略.........