diff --git a/go.mod b/go.mod index 13323db..88646cd 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,5 @@ go 1.12 require ( github.com/gorilla/mux v1.7.3 github.com/stretchr/testify v1.3.0 + github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30 ) diff --git a/go.sum b/go.sum index c2eb794..ad0aca6 100644 --- a/go.sum +++ b/go.sum @@ -7,3 +7,5 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30 h1:kZiWylALnUy4kzoKJemjH8eqwCl3RjW1r1ITCjjW7G8= +github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= diff --git a/internal/backend.go b/internal/backend.go index 61b9a07..614c0a2 100644 --- a/internal/backend.go +++ b/internal/backend.go @@ -21,6 +21,7 @@ type Backend interface { GetEventByID(id string) rooms.Event PutEvent(rooms.Event) error GetRoomByAlias(string) Room + GetEventsSince(sinceToken string, limit int) []rooms.Event } type Room interface { diff --git a/internal/backends/memory/backend.go b/internal/backends/memory/backend.go index 1fcb3bb..6aecca3 100644 --- a/internal/backends/memory/backend.go +++ b/internal/backends/memory/backend.go @@ -6,6 +6,7 @@ import ( "sort" "strings" "sync" + "time" "github.com/signaller-matrix/signaller/internal" "github.com/signaller-matrix/signaller/internal/models" @@ -13,12 +14,13 @@ import ( "github.com/signaller-matrix/signaller/internal/models/createroom" "github.com/signaller-matrix/signaller/internal/models/rooms" mSync "github.com/signaller-matrix/signaller/internal/models/sync" + "github.com/wangjia184/sortedset" ) type Backend struct { data map[string]internal.User rooms map[string]internal.Room - events map[string]rooms.Event + events *sortedset.SortedSet roomAliases map[string]internal.Room hostname string validateUsernameFunc func(string) error // TODO: create ability to redefine validation func @@ -35,7 +37,7 @@ func NewBackend(hostname string) *Backend { validateUsernameFunc: defaultValidationUsernameFunc, rooms: make(map[string]internal.Room), roomAliases: make(map[string]internal.Room), - events: make(map[string]rooms.Event), + events: sortedset.New(), data: make(map[string]internal.User)} } @@ -187,14 +189,57 @@ func (backend *Backend) GetEventByID(id string) rooms.Event { backend.mutex.RLock() defer backend.mutex.RUnlock() - return backend.events[id] + return backend.events.GetByKey(id).Value.(rooms.Event) } func (backend *Backend) PutEvent(event rooms.Event) error { backend.mutex.Lock() defer backend.mutex.Unlock() - backend.events[event.EventID] = event + backend.events.AddOrUpdate(event.EventID, sortedset.SCORE(time.Now().Unix()), event) return nil } + +func (backend *Backend) GetEventsSince(user User, sinceToken string, limit int) []rooms.Event { + sinceEventNode := backend.events.GetByKey(sinceToken) + sEvents := backend.events.GetByScoreRange(sinceEventNode.Score(), -1, &sortedset.GetByScoreRangeOptions{ + Limit: limit, + }) + + events := extractEventsFromNodes(sEvents) + + var returnEvents []rooms.Event + for _, event := range events { + if isEventRelatedToUser(event, user) { + returnEvents = append(returnEvents, event) + } + } + + return returnEvents +} + +func extractEventsFromNodes(nodes []*sortedset.SortedSetNode) []rooms.Event { + var events []rooms.Event + for _, e := range nodes { + events = append(events, e.Value.(rooms.Event)) + } + + return events +} + +func isEventRelatedToUser(event rooms.Event, user User) bool { + if internal.InArray(event.RoomID, extractRoomIDsFromModel(user.JoinedRooms())) { + return true + } + return false +} + +func extractRoomIDsFromModel(rooms []internal.Room) []string { + var roomIDs []string + for _, room := range rooms { + roomIDs = append(roomIDs, room.ID()) + } + + return roomIDs +} diff --git a/internal/utils.go b/internal/utils.go index 7cd7aa7..8b16494 100644 --- a/internal/utils.go +++ b/internal/utils.go @@ -37,3 +37,12 @@ func roomsToPublicRoomsChunks(rooms []Room) []publicrooms.PublicRoomsChunk { return chunks } + +func InArray(a string, arr []string) bool { + for _, b := range arr { + if b == a { + return true + } + } + return false +}