BoltDB中的键顺序

huangapple go评论73阅读模式
英文:

Key Order in BoltDB

问题

boltdb的键应该使用哪种字节序?我应该先获取机器的字节序然后使用它吗?

我需要键按正确的顺序排序 - 就像字节序列一样,没有特定的逻辑来对它们进行排序。例如,在这里应该使用哪种字节序(Key是一个顺序的id,类似于mongodb的一个):

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"log"
	"time"

	"github.com/boltdb/bolt"
)

var (
	Endian = binary.BigEndian // 哪种字节序?
)

func main() {
	db, err := bolt.Open("temp.db", 0600, nil)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	defer time.Sleep(time.Second)

	tempBucket := []byte("TMP")

	db.Update(func(tx *bolt.Tx) error {
		data := Row{
			Key: Key{
				Head:    0x1A1A1A,
				Mark:    0x1010,
				Counter: 0x01,
			},
			At:      time.Now().UTC().Unix(),
			Payload: 10,
		}

		keyBytes, err := marshal(&data.Key)
		if err != nil {
			return erp(err)
		}

		dataBytes, err := marshal(&data)
		if err != nil {
			return erp(err)
		}

		b, err := tx.CreateBucketIfNotExists(tempBucket)
		if err != nil {
			return erp(err)
		}

		err = b.Put(keyBytes, dataBytes)
		if err != nil {
			return erp(err)
		}

		return nil
	})

	db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket(tempBucket)

		c := b.Cursor()

		for k, v := c.First(); k != nil; k, v = c.Next() {
			k, v := k, v
			fmt.Println(k, v)

			dt := Row{}
			err := unmarshal(&dt, v)
			if err != nil {
				return erp(err)
			}
			fmt.Printf("key=%X, value=%v\n", k, dt)
		}

		return nil
	})
}

func erp(e error) error {
	log.Println(e)
	return e
}

func marshal(pointerToData interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	err := binary.Write(buf, Endian, pointerToData)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func unmarshal(pointerToData interface{}, bs []byte) error {
	buffer := bytes.NewBuffer(bs)
	err := binary.Read(buffer, Endian, pointerToData)
	if err != nil {
		return err
	}
	return nil
}

type Row struct {
	Key
	At      int64
	Payload int64
}

type Key struct {
	Head    uint32
	Mark    uint16
	Counter uint16
}
英文:

Which endian should be used for a boltdb's key? Should I get the endian of the machine first and use that?

I need the keys to be ordered properly - just as a sequence of bytes, no specific logic for ordering them. For example which endian should be used here (the Key is a sequential id, like a mongodb's one):

package main
import (
"bytes"
"encoding/binary"
"fmt"
"log"
"time"
"github.com/boltdb/bolt"
)
var (
Endian = binary.BigEndian // Which endian?
)
func main() {
db, err := bolt.Open("temp.db", 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
defer time.Sleep(time.Second)
tempBucket := []byte("TMP")
db.Update(func(tx *bolt.Tx) error {
data := Row{
Key: Key{
Head:    0x1A1A1A,
Mark:    0x1010,
Counter: 0x01,
},
At:      time.Now().UTC().Unix(),
Payload: 10,
}
keyBytes, err := marshal(&data.Key)
if err != nil {
return erp(err)
}
dataBytes, err := marshal(&data)
if err != nil {
return erp(err)
}
b, err := tx.CreateBucketIfNotExists(tempBucket)
if err != nil {
return erp(err)
}
err = b.Put(keyBytes, dataBytes)
if err != nil {
return erp(err)
}
return nil
})
db.View(func(tx *bolt.Tx) error {
b := tx.Bucket(tempBucket)
c := b.Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
k, v := k, v
fmt.Println(k, v)
dt := Row{}
err := unmarshal(&dt, v)
if err != nil {
return erp(err)
}
fmt.Printf("key=%X, value=%v\n", k, dt)
}
return nil
})
}
func erp(e error) error {
log.Println(e)
return e
}
func marshal(pointerToData interface{}) ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, Endian, pointerToData)
if err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func unmarshal(pointerToData interface{}, bs []byte) error {
buffer := bytes.NewBuffer(bs)
err := binary.Read(buffer, Endian, pointerToData)
if err != nil {
return err
}
return nil
}
type Row struct {
Key
At      int64
Payload int64
}
type Key struct {
Head    uint32
Mark    uint16
Counter uint16
}

答案1

得分: 2

为了使键自然排序,请使用BigEndian。

在LittleEndian中,字节被交换,这将导致键的顺序不正确。

英文:

To have the keys naturally ordered, use BigEndian

In LittleEndian, the bytes are swapped, which would give it to you out of order.

huangapple
  • 本文由 发表于 2016年2月3日 22:19:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/35179563.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定