github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/swarm/shed/field_uint64.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:44</date>
    10  //</624450117809737728>
    11  
    12  
    13  package shed
    14  
    15  import (
    16  	"encoding/binary"
    17  
    18  	"github.com/syndtr/goleveldb/leveldb"
    19  )
    20  
    21  //uint64字段提供了一种在数据库中使用简单计数器的方法。
    22  //它透明地将uint64类型值编码为字节。
    23  type Uint64Field struct {
    24  	db  *DB
    25  	key []byte
    26  }
    27  
    28  //newuint64字段返回新的uint64字段。
    29  //它根据数据库模式验证其名称和类型。
    30  func (db *DB) NewUint64Field(name string) (f Uint64Field, err error) {
    31  	key, err := db.schemaFieldKey(name, "uint64")
    32  	if err != nil {
    33  		return f, err
    34  	}
    35  	return Uint64Field{
    36  		db:  db,
    37  		key: key,
    38  	}, nil
    39  }
    40  
    41  //get从数据库中检索uint64值。
    42  //如果在数据库中找不到该值,则为0
    43  //返回,没有错误。
    44  func (f Uint64Field) Get() (val uint64, err error) {
    45  	b, err := f.db.Get(f.key)
    46  	if err != nil {
    47  		if err == leveldb.ErrNotFound {
    48  			return 0, nil
    49  		}
    50  		return 0, err
    51  	}
    52  	return binary.BigEndian.Uint64(b), nil
    53  }
    54  
    55  //放入编码uin64值并将其存储在数据库中。
    56  func (f Uint64Field) Put(val uint64) (err error) {
    57  	return f.db.Put(f.key, encodeUint64(val))
    58  }
    59  
    60  //Putinbatch在批中存储uint64值
    61  //以后可以保存到数据库中。
    62  func (f Uint64Field) PutInBatch(batch *leveldb.Batch, val uint64) {
    63  	batch.Put(f.key, encodeUint64(val))
    64  }
    65  
    66  //inc在数据库中增加uint64值。
    67  //此操作不是goroutine save。
    68  func (f Uint64Field) Inc() (val uint64, err error) {
    69  	val, err = f.Get()
    70  	if err != nil {
    71  		if err == leveldb.ErrNotFound {
    72  			val = 0
    73  		} else {
    74  			return 0, err
    75  		}
    76  	}
    77  	val++
    78  	return val, f.Put(val)
    79  }
    80  
    81  //incinbatch在批中增加uint64值
    82  //通过从数据库中检索值,而不是同一批。
    83  //此操作不是goroutine save。
    84  func (f Uint64Field) IncInBatch(batch *leveldb.Batch) (val uint64, err error) {
    85  	val, err = f.Get()
    86  	if err != nil {
    87  		if err == leveldb.ErrNotFound {
    88  			val = 0
    89  		} else {
    90  			return 0, err
    91  		}
    92  	}
    93  	val++
    94  	f.PutInBatch(batch, val)
    95  	return val, nil
    96  }
    97  
    98  //DEC减少数据库中的uint64值。
    99  //此操作不是goroutine save。
   100  //该字段受到保护,不会溢出为负值。
   101  func (f Uint64Field) Dec() (val uint64, err error) {
   102  	val, err = f.Get()
   103  	if err != nil {
   104  		if err == leveldb.ErrNotFound {
   105  			val = 0
   106  		} else {
   107  			return 0, err
   108  		}
   109  	}
   110  	if val != 0 {
   111  		val--
   112  	}
   113  	return val, f.Put(val)
   114  }
   115  
   116  //decinbatch在批处理中递减uint64值
   117  //通过从数据库中检索值,而不是同一批。
   118  //此操作不是goroutine save。
   119  //该字段受到保护,不会溢出为负值。
   120  func (f Uint64Field) DecInBatch(batch *leveldb.Batch) (val uint64, err error) {
   121  	val, err = f.Get()
   122  	if err != nil {
   123  		if err == leveldb.ErrNotFound {
   124  			val = 0
   125  		} else {
   126  			return 0, err
   127  		}
   128  	}
   129  	if val != 0 {
   130  		val--
   131  	}
   132  	f.PutInBatch(batch, val)
   133  	return val, nil
   134  }
   135  
   136  //编码将uint64转换为8字节长
   137  //以big-endian编码切片。
   138  func encodeUint64(val uint64) (b []byte) {
   139  	b = make([]byte, 8)
   140  	binary.BigEndian.PutUint64(b, val)
   141  	return b
   142  }
   143