Use firebase push IDs for messages

This commit is contained in:
Ken-Håvard Lieng 2017-04-20 05:32:22 +02:00
parent 0413960b85
commit 2525b06c28
16 changed files with 288 additions and 91 deletions

View file

@ -21,7 +21,7 @@ struct Channel {
}
struct Message {
ID uint64
ID string
From string
Content string
Time int64

View file

@ -702,6 +702,21 @@ func (d *Channel) Unmarshal(buf []byte) (uint64, error) {
func (d *Message) Size() (s uint64) {
{
l := uint64(len(d.ID))
{
t := l
for t >= 0x80 {
t >>= 7
s++
}
s++
}
s += l
}
{
l := uint64(len(d.From))
@ -732,7 +747,7 @@ func (d *Message) Size() (s uint64) {
}
s += l
}
s += 16
s += 8
return
}
func (d *Message) Marshal(buf []byte) ([]byte, error) {
@ -747,9 +762,23 @@ func (d *Message) Marshal(buf []byte) ([]byte, error) {
i := uint64(0)
{
l := uint64(len(d.ID))
*(*uint64)(unsafe.Pointer(&buf[0])) = d.ID
{
t := uint64(l)
for t >= 0x80 {
buf[i+0] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+0] = byte(t)
i++
}
copy(buf[i+0:], d.ID)
i += l
}
{
l := uint64(len(d.From))
@ -759,15 +788,15 @@ func (d *Message) Marshal(buf []byte) ([]byte, error) {
t := uint64(l)
for t >= 0x80 {
buf[i+8] = byte(t) | 0x80
buf[i+0] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+8] = byte(t)
buf[i+0] = byte(t)
i++
}
copy(buf[i+8:], d.From)
copy(buf[i+0:], d.From)
i += l
}
{
@ -778,43 +807,38 @@ func (d *Message) Marshal(buf []byte) ([]byte, error) {
t := uint64(l)
for t >= 0x80 {
buf[i+8] = byte(t) | 0x80
buf[i+0] = byte(t) | 0x80
t >>= 7
i++
}
buf[i+8] = byte(t)
buf[i+0] = byte(t)
i++
}
copy(buf[i+8:], d.Content)
copy(buf[i+0:], d.Content)
i += l
}
{
*(*int64)(unsafe.Pointer(&buf[i+8])) = d.Time
*(*int64)(unsafe.Pointer(&buf[i+0])) = d.Time
}
return buf[:i+16], nil
return buf[:i+8], nil
}
func (d *Message) Unmarshal(buf []byte) (uint64, error) {
i := uint64(0)
{
d.ID = *(*uint64)(unsafe.Pointer(&buf[i+0]))
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+8] & 0x7F)
for buf[i+8]&0x80 == 0x80 {
t := uint64(buf[i+0] & 0x7F)
for buf[i+0]&0x80 == 0x80 {
i++
t |= uint64(buf[i+8]&0x7F) << bs
t |= uint64(buf[i+0]&0x7F) << bs
bs += 7
}
i++
@ -822,7 +846,7 @@ func (d *Message) Unmarshal(buf []byte) (uint64, error) {
l = t
}
d.From = string(buf[i+8 : i+8+l])
d.ID = string(buf[i+0 : i+0+l])
i += l
}
{
@ -831,10 +855,10 @@ func (d *Message) Unmarshal(buf []byte) (uint64, error) {
{
bs := uint8(7)
t := uint64(buf[i+8] & 0x7F)
for buf[i+8]&0x80 == 0x80 {
t := uint64(buf[i+0] & 0x7F)
for buf[i+0]&0x80 == 0x80 {
i++
t |= uint64(buf[i+8]&0x7F) << bs
t |= uint64(buf[i+0]&0x7F) << bs
bs += 7
}
i++
@ -842,13 +866,33 @@ func (d *Message) Unmarshal(buf []byte) (uint64, error) {
l = t
}
d.Content = string(buf[i+8 : i+8+l])
d.From = string(buf[i+0 : i+0+l])
i += l
}
{
l := uint64(0)
{
bs := uint8(7)
t := uint64(buf[i+0] & 0x7F)
for buf[i+0]&0x80 == 0x80 {
i++
t |= uint64(buf[i+0]&0x7F) << bs
bs += 7
}
i++
l = t
}
d.Content = string(buf[i+0 : i+0+l])
i += l
}
{
d.Time = *(*int64)(unsafe.Pointer(&buf[i+8]))
d.Time = *(*int64)(unsafe.Pointer(&buf[i+0]))
}
return i + 16, nil
return i + 8, nil
}

View file

@ -2,8 +2,6 @@ package storage
import (
"os"
"strconv"
"strings"
"time"
"github.com/blevesearch/bleve"
@ -12,7 +10,7 @@ import (
)
type Message struct {
ID uint64 `json:"id" bleve:"-"`
ID string `json:"id" bleve:"-"`
Server string `json:"-" bleve:"server"`
From string `json:"from" bleve:"-"`
To string `json:"-" bleve:"to"`
@ -24,37 +22,35 @@ func (m Message) Type() string {
return "message"
}
func (u *User) LogMessage(server, from, to, content string) error {
func (u *User) LogMessage(id, server, from, to, content string) error {
message := Message{
ID: id,
Server: server,
From: from,
To: to,
Content: content,
Time: time.Now().Unix(),
}
bucketKey := server + ":" + to
err := u.messageLog.Batch(func(tx *bolt.Tx) error {
b, err := tx.Bucket(bucketMessages).CreateBucketIfNotExists([]byte(bucketKey))
b, err := tx.Bucket(bucketMessages).CreateBucketIfNotExists([]byte(server + ":" + to))
if err != nil {
return err
}
message.ID, _ = b.NextSequence()
data, err := message.Marshal(nil)
if err != nil {
return err
}
return b.Put(idToBytes(message.ID), data)
return b.Put([]byte(id), data)
})
if err != nil {
return err
}
return u.messageIndex.Index(bucketKey+":"+strconv.FormatUint(message.ID, 10), message)
return u.messageIndex.Index(id, message)
}
func (u *User) GetLastMessages(server, channel string, count int) ([]Message, error) {
@ -85,7 +81,7 @@ func (u *User) GetLastMessages(server, channel string, count int) ([]Message, er
return nil, nil
}
func (u *User) GetMessages(server, channel string, count int, fromID uint64) ([]Message, error) {
func (u *User) GetMessages(server, channel string, count int, fromID string) ([]Message, error) {
messages := make([]Message, count)
u.messageLog.View(func(tx *bolt.Tx) error {
@ -95,7 +91,7 @@ func (u *User) GetMessages(server, channel string, count int, fromID uint64) ([]
}
c := b.Cursor()
c.Seek(idToBytes(fromID))
c.Seek([]byte(fromID))
for k, v := c.Prev(); count > 0 && k != nil; k, v = c.Prev() {
count--
@ -134,15 +130,11 @@ func (u *User) SearchMessages(server, channel, q string) ([]Message, error) {
messages := []Message{}
u.messageLog.View(func(tx *bolt.Tx) error {
b := tx.Bucket(bucketMessages)
b := tx.Bucket(bucketMessages).Bucket([]byte(server + ":" + channel))
for _, hit := range searchResults.Hits {
idx := strings.LastIndex(hit.ID, ":")
bc := b.Bucket([]byte(hit.ID[:idx]))
id, _ := strconv.ParseUint(hit.ID[idx+1:], 10, 64)
message := Message{}
message.Unmarshal(bc.Get(idToBytes(id)))
message.Unmarshal(b.Get([]byte(hit.ID)))
messages = append(messages, message)
}

View file

@ -6,6 +6,7 @@ import (
"strconv"
"testing"
"github.com/kjk/betterguid"
"github.com/stretchr/testify/assert"
)
@ -87,7 +88,7 @@ func TestMessages(t *testing.T) {
user, err := NewUser()
assert.Nil(t, err)
messages, err := user.GetMessages("irc.freenode.net", "#go-nuts", 10, 6)
messages, err := user.GetMessages("irc.freenode.net", "#go-nuts", 10, "6")
assert.Nil(t, err)
assert.Len(t, messages, 0)
@ -99,28 +100,31 @@ func TestMessages(t *testing.T) {
assert.Nil(t, err)
assert.Len(t, messages, 0)
ids := []string{}
for i := 0; i < 5; i++ {
err = user.LogMessage("irc.freenode.net", "nick", "#go-nuts", "message"+strconv.Itoa(i))
id := betterguid.New()
ids = append(ids, id)
err = user.LogMessage(id, "irc.freenode.net", "nick", "#go-nuts", "message"+strconv.Itoa(i))
assert.Nil(t, err)
}
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, 6)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, ids[4])
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message3", messages[3].Content)
assert.Nil(t, err)
assert.Len(t, messages, 4)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, betterguid.New())
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message4", messages[4].Content)
assert.Nil(t, err)
assert.Len(t, messages, 5)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, 100)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, ids[2])
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message4", messages[4].Content)
assert.Equal(t, "message1", messages[1].Content)
assert.Nil(t, err)
assert.Len(t, messages, 5)
messages, err = user.GetMessages("irc.freenode.net", "#go-nuts", 10, 4)
assert.Equal(t, "message0", messages[0].Content)
assert.Equal(t, "message2", messages[2].Content)
assert.Nil(t, err)
assert.Len(t, messages, 3)
assert.Len(t, messages, 2)
messages, err = user.GetLastMessages("irc.freenode.net", "#go-nuts", 10)
assert.Equal(t, "message0", messages[0].Content)