Rename State to StateSnapshot

This commit is contained in:
Mark Haines 2017-02-13 18:22:02 +00:00
parent 48e2edab0d
commit 91b10ef956
5 changed files with 51 additions and 51 deletions

View file

@ -28,14 +28,14 @@ type RoomEventDatabase interface {
StateAtEventIDs(eventIDs []string) ([]types.StateAtEvent, error) StateAtEventIDs(eventIDs []string) ([]types.StateAtEvent, error)
// Lookup the numeric state data IDs for the each numeric state ID // Lookup the numeric state data IDs for the each numeric state ID
// The returned slice is sorted by numeric state ID. // The returned slice is sorted by numeric state ID.
StateDataNIDs(stateNIDs []types.StateNID) ([]types.StateDataNIDList, error) StateDataNIDs(stateNIDs []types.StateSnapshotNID) ([]types.StateDataNIDList, error)
// Lookup the state data for each numeric state data ID // Lookup the state data for each numeric state data ID
// The returned slice is sorted by numeric state data ID. // The returned slice is sorted by numeric state data ID.
StateEntries(stateDataNIDs []types.StateDataNID) ([]types.StateEntryList, error) StateEntries(stateDataNIDs []types.StateDataNID) ([]types.StateEntryList, error)
// Store the room state at an event in the database // Store the room state at an event in the database
AddState(roomNID types.RoomNID, stateDataNIDs []types.StateDataNID, state []types.StateEntry) (types.StateNID, error) AddState(roomNID types.RoomNID, stateDataNIDs []types.StateDataNID, state []types.StateEntry) (types.StateSnapshotNID, error)
// Set the state at an event. // Set the state at an event.
SetState(eventNID types.EventNID, stateNID types.StateNID) error SetState(eventNID types.EventNID, stateNID types.StateSnapshotNID) error
} }
func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error { func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error {
@ -64,13 +64,13 @@ func processRoomEvent(db RoomEventDatabase, input api.InputRoomEvent) error {
return nil return nil
} }
if stateAtEvent.BeforeStateNID == 0 { if stateAtEvent.BeforeStateSnapshotNID == 0 {
// We haven't calculated a state for this event yet. // We haven't calculated a state for this event yet.
// Lets calculate one. // Lets calculate one.
if stateAtEvent.BeforeStateNID, err = calculateAndStoreState(db, event, roomNID, input.StateEventIDs); err != nil { if stateAtEvent.BeforeStateSnapshotNID, err = calculateAndStoreState(db, event, roomNID, input.StateEventIDs); err != nil {
return err return err
} }
db.SetState(stateAtEvent.EventNID, stateAtEvent.BeforeStateNID) db.SetState(stateAtEvent.EventNID, stateAtEvent.BeforeStateSnapshotNID)
} }
// TODO: // TODO:

View file

@ -9,7 +9,7 @@ import (
func calculateAndStoreState( func calculateAndStoreState(
db RoomEventDatabase, event gomatrixserverlib.Event, roomNID types.RoomNID, stateEventIDs []string, db RoomEventDatabase, event gomatrixserverlib.Event, roomNID types.RoomNID, stateEventIDs []string,
) (types.StateNID, error) { ) (types.StateSnapshotNID, error) {
if stateEventIDs != nil { if stateEventIDs != nil {
// 1) We've been told what the state at the event is. // 1) We've been told what the state at the event is.
// Check that those state events are in the database and store the state. // Check that those state events are in the database and store the state.
@ -46,11 +46,11 @@ func calculateAndStoreState(
// have the same state, so this event has exactly the same state // have the same state, so this event has exactly the same state
// as the previous events. // as the previous events.
// This should be the common case. // This should be the common case.
return prevState.BeforeStateNID, nil return prevState.BeforeStateSnapshotNID, nil
} }
// The previous event was a state event so we need to store a copy // The previous event was a state event so we need to store a copy
// of the previous state updated with that event. // of the previous state updated with that event.
stateDataNIDLists, err := db.StateDataNIDs([]types.StateNID{prevState.BeforeStateNID}) stateDataNIDLists, err := db.StateDataNIDs([]types.StateSnapshotNID{prevState.BeforeStateSnapshotNID})
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -70,14 +70,14 @@ func calculateAndStoreState(
const maxStateDataNIDs = 64 const maxStateDataNIDs = 64
func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, prevStates []types.StateAtEvent) (types.StateNID, error) { func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, prevStates []types.StateAtEvent) (types.StateSnapshotNID, error) {
// Conflict resolution. // Conflict resolution.
// First stage: load the state datablocks for the prev events. // First stage: load the state datablocks for the prev events.
stateNIDs := make([]types.StateNID, len(prevStates)) stateNIDs := make([]types.StateSnapshotNID, len(prevStates))
for i, state := range prevStates { for i, state := range prevStates {
stateNIDs[i] = state.BeforeStateNID stateNIDs[i] = state.BeforeStateSnapshotNID
} }
stateDataNIDLists, err := db.StateDataNIDs(uniqueStateNIDs(stateNIDs)) stateDataNIDLists, err := db.StateDataNIDs(uniqueStateSnapshotNIDs(stateNIDs))
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -95,11 +95,11 @@ func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, pre
var combined []types.StateEntry var combined []types.StateEntry
for _, prevState := range prevStates { for _, prevState := range prevStates {
list, ok := stateDataNIDsMap.lookup(prevState.BeforeStateNID) list, ok := stateDataNIDsMap.lookup(prevState.BeforeStateSnapshotNID)
if !ok { if !ok {
// This should only get hit if the database is corrupt. // This should only get hit if the database is corrupt.
// It should be impossible for an event to reference a NID that doesn't exist // It should be impossible for an event to reference a NID that doesn't exist
panic(fmt.Errorf("Corrupt DB: Missing state numeric ID %d", prevState.BeforeStateNID)) panic(fmt.Errorf("Corrupt DB: Missing state numeric ID %d", prevState.BeforeStateSnapshotNID))
} }
var fullState []types.StateEntry var fullState []types.StateEntry
@ -108,7 +108,7 @@ func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, pre
if !ok { if !ok {
// This should only get hit if the database is corrupt. // This should only get hit if the database is corrupt.
// It should be impossible for an event to reference a NID that doesn't exist // It should be impossible for an event to reference a NID that doesn't exist
panic(fmt.Errorf("Corrupt DB: Missing state numeric ID %d", prevState.BeforeStateNID)) panic(fmt.Errorf("Corrupt DB: Missing state numeric ID %d", prevState.BeforeStateSnapshotNID))
} }
fullState = append(fullState, entries...) fullState = append(fullState, entries...)
} }
@ -121,7 +121,7 @@ func calculateAndStoreStateMany(db RoomEventDatabase, roomNID types.RoomNID, pre
sort.Stable(stateEntryByStateKeySorter(fullState)) sort.Stable(stateEntryByStateKeySorter(fullState))
// Unique returns the last entry for each state key. // Unique returns the last entry for each state key.
fullState = fullState[:unique(stateEntryByStateKeySorter(fullState))] fullState = fullState[:unique(stateEntryByStateKeySorter(fullState))]
// Add the full state for this StateNID. // Add the full state for this StateSnapshotNID.
combined = append(combined, fullState...) combined = append(combined, fullState...)
} }
@ -174,12 +174,12 @@ func duplicateStateKeys(a []types.StateEntry) []types.StateEntry {
type stateDataNIDListMap []types.StateDataNIDList type stateDataNIDListMap []types.StateDataNIDList
func (m stateDataNIDListMap) lookup(stateNID types.StateNID) (stateDataNIDs []types.StateDataNID, ok bool) { func (m stateDataNIDListMap) lookup(stateNID types.StateSnapshotNID) (stateDataNIDs []types.StateDataNID, ok bool) {
list := []types.StateDataNIDList(m) list := []types.StateDataNIDList(m)
i := sort.Search(len(list), func(i int) bool { i := sort.Search(len(list), func(i int) bool {
return list[i].StateNID >= stateNID return list[i].StateSnapshotNID >= stateNID
}) })
if i < len(list) && list[i].StateNID == stateNID { if i < len(list) && list[i].StateSnapshotNID == stateNID {
ok = true ok = true
stateDataNIDs = list[i].StateDataNIDs stateDataNIDs = list[i].StateDataNIDs
} }
@ -214,13 +214,13 @@ func (s stateEntrySorter) Len() int { return len(s) }
func (s stateEntrySorter) Less(i, j int) bool { return s[i].LessThan(s[j]) } func (s stateEntrySorter) Less(i, j int) bool { return s[i].LessThan(s[j]) }
func (s stateEntrySorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s stateEntrySorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type stateNIDSorter []types.StateNID type stateNIDSorter []types.StateSnapshotNID
func (s stateNIDSorter) Len() int { return len(s) } func (s stateNIDSorter) Len() int { return len(s) }
func (s stateNIDSorter) Less(i, j int) bool { return s[i] < s[j] } func (s stateNIDSorter) Less(i, j int) bool { return s[i] < s[j] }
func (s stateNIDSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s stateNIDSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func uniqueStateNIDs(nids []types.StateNID) []types.StateNID { func uniqueStateSnapshotNIDs(nids []types.StateSnapshotNID) []types.StateSnapshotNID {
sort.Sort(stateNIDSorter(nids)) sort.Sort(stateNIDSorter(nids))
return nids[:unique(stateNIDSorter(nids))] return nids[:unique(stateNIDSorter(nids))]
} }

View file

@ -352,7 +352,7 @@ CREATE TABLE IF NOT EXISTS events (
-- part of the event graph -- part of the event graph
-- Since many different events can have the same state we store the -- Since many different events can have the same state we store the
-- state into a separate state table and refer to it by numeric ID. -- state into a separate state table and refer to it by numeric ID.
state_nid bigint NOT NULL DEFAULT 0 state_snapshot_nid bigint NOT NULL DEFAULT 0
-- The textual event id. -- The textual event id.
-- Used to lookup the numeric ID when processing requests. -- Used to lookup the numeric ID when processing requests.
-- Needed for state resolution. -- Needed for state resolution.
@ -371,7 +371,7 @@ const insertEventSQL = "" +
" VALUES ($1, $2, $3, $4, $5, $6)" + " VALUES ($1, $2, $3, $4, $5, $6)" +
" ON CONFLICT ON CONSTRAINT event_id_unique" + " ON CONFLICT ON CONSTRAINT event_id_unique" +
" DO UPDATE SET event_id = $1" + " DO UPDATE SET event_id = $1" +
" RETURNING event_nid, state_nid" " RETURNING event_nid, state_snapshot_nid"
// Bulk lookup of events by string ID. // Bulk lookup of events by string ID.
// Sort by the numeric IDs for event type and state key. // Sort by the numeric IDs for event type and state key.
@ -382,12 +382,12 @@ const bulkSelectStateEventByIDSQL = "" +
" ORDER BY event_type_nid, event_state_key_nid ASC" " ORDER BY event_type_nid, event_state_key_nid ASC"
const bulkSelectStateAtEventByIDSQL = "" + const bulkSelectStateAtEventByIDSQL = "" +
"SELECT event_type_nid, event_state_key_nid, event_nid, state_nid FROM events" + "SELECT event_type_nid, event_state_key_nid, event_nid, state_snapshot_nid FROM events" +
" WHERE event_id = ANY($1)" + " WHERE event_id = ANY($1)" +
" ORDER BY event_type_nid, event_state_key_nid ASC" " ORDER BY event_type_nid, event_state_key_nid ASC"
const updateEventStateSQL = "" + const updateEventStateSQL = "" +
"UPDATE events SET state_nid = $2 WHERE event_nid = $1" "UPDATE events SET state_snapshot_nid = $2 WHERE event_nid = $1"
func (s *statements) prepareEvents(db *sql.DB) (err error) { func (s *statements) prepareEvents(db *sql.DB) (err error) {
_, err = db.Exec(eventsSchema) _, err = db.Exec(eventsSchema)
@ -414,7 +414,7 @@ func (s *statements) insertEvent(
eventID string, eventID string,
referenceSHA256 []byte, referenceSHA256 []byte,
authEventNIDs []types.EventNID, authEventNIDs []types.EventNID,
) (types.EventNID, types.StateNID, error) { ) (types.EventNID, types.StateSnapshotNID, error) {
nids := make([]int64, len(authEventNIDs)) nids := make([]int64, len(authEventNIDs))
for i := range authEventNIDs { for i := range authEventNIDs {
nids[i] = int64(authEventNIDs[i]) nids[i] = int64(authEventNIDs[i])
@ -425,7 +425,7 @@ func (s *statements) insertEvent(
int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID), eventID, referenceSHA256, int64(roomNID), int64(eventTypeNID), int64(eventStateKeyNID), eventID, referenceSHA256,
pq.Int64Array(nids), pq.Int64Array(nids),
).Scan(&eventNID, &stateNID) ).Scan(&eventNID, &stateNID)
return types.EventNID(eventNID), types.StateNID(stateNID), err return types.EventNID(eventNID), types.StateSnapshotNID(stateNID), err
} }
func (s *statements) bulkSelectStateEventByID(eventIDs []string) ([]types.StateEntry, error) { func (s *statements) bulkSelectStateEventByID(eventIDs []string) ([]types.StateEntry, error) {
@ -475,11 +475,11 @@ func (s *statements) bulkSelectStateAtEventByID(eventIDs []string) ([]types.Stat
&result.EventNID, &result.EventNID,
&result.EventTypeNID, &result.EventTypeNID,
&result.EventStateKeyNID, &result.EventStateKeyNID,
&result.BeforeStateNID, &result.BeforeStateSnapshotNID,
); err != nil { ); err != nil {
return nil, err return nil, err
} }
if result.BeforeStateNID == 0 { if result.BeforeStateSnapshotNID == 0 {
return nil, fmt.Errorf("storage: missing state for event NID %d", result.EventNID) return nil, fmt.Errorf("storage: missing state for event NID %d", result.EventNID)
} }
} }
@ -489,7 +489,7 @@ func (s *statements) bulkSelectStateAtEventByID(eventIDs []string) ([]types.Stat
return results, err return results, err
} }
func (s *statements) updateEventState(eventNID types.EventNID, stateNID types.StateNID) error { func (s *statements) updateEventState(eventNID types.EventNID, stateNID types.StateSnapshotNID) error {
_, err := s.updateEventStateStmt.Exec(int64(eventNID), int64(stateNID)) _, err := s.updateEventStateStmt.Exec(int64(eventNID), int64(stateNID))
return err return err
} }
@ -586,10 +586,10 @@ const stateSchema = `
-- because room state tends to accumulate small changes over time. Although if -- because room state tends to accumulate small changes over time. Although if
-- the list of deltas becomes too long it becomes more efficient to encode -- the list of deltas becomes too long it becomes more efficient to encode
-- the full state under single state_data_nid. -- the full state under single state_data_nid.
CREATE SEQUENCE IF NOT EXISTS state_nid_seq; CREATE SEQUENCE IF NOT EXISTS state_snapshot_nid_seq;
CREATE TABLE IF NOT EXISTS state ( CREATE TABLE IF NOT EXISTS state_snapshots (
-- Local numeric ID for the state. -- Local numeric ID for the state.
state_nid bigint PRIMARY KEY DEFAULT nextval('state_nid_seq'), state_snapshot_nid bigint PRIMARY KEY DEFAULT nextval('state_snapshot_nid_seq'),
-- Local numeric ID of the room this state is for. -- Local numeric ID of the room this state is for.
-- Unused in normal operation, but useful for background work or ad-hoc debugging. -- Unused in normal operation, but useful for background work or ad-hoc debugging.
room_nid bigint NOT NULL, room_nid bigint NOT NULL,
@ -599,13 +599,13 @@ CREATE TABLE IF NOT EXISTS state (
` `
const insertStateSQL = "" + const insertStateSQL = "" +
"INSERT INTO state (room_nid, state_data_nids)" + "INSERT INTO state_snapshots (room_nid, state_data_nids)" +
" VALUES ($1, $2)" + " VALUES ($1, $2)" +
" RETURNING state_nid" " RETURNING state_snapshot_nid"
const bulkSelectStateDataNIDsSQL = "" + const bulkSelectStateDataNIDsSQL = "" +
"SELECT state_nid, state_data_nids FROM state" + "SELECT state_snapshot_nid, state_data_nids FROM state_snapshots" +
" WHERE state_nid = ANY($1) ORDER BY state_nid" " WHERE state_snapshot_nid = ANY($1) ORDER BY state_snapshot_nid"
func (s *statements) prepareState(db *sql.DB) (err error) { func (s *statements) prepareState(db *sql.DB) (err error) {
_, err = db.Exec(stateSchema) _, err = db.Exec(stateSchema)
@ -621,7 +621,7 @@ func (s *statements) prepareState(db *sql.DB) (err error) {
return return
} }
func (s *statements) insertState(roomNID types.RoomNID, stateDataNIDs []types.StateDataNID) (stateNID types.StateNID, err error) { func (s *statements) insertState(roomNID types.RoomNID, stateDataNIDs []types.StateDataNID) (stateNID types.StateSnapshotNID, err error) {
nids := make([]int64, len(stateDataNIDs)) nids := make([]int64, len(stateDataNIDs))
for i := range stateDataNIDs { for i := range stateDataNIDs {
nids[i] = int64(stateDataNIDs[i]) nids[i] = int64(stateDataNIDs[i])
@ -630,7 +630,7 @@ func (s *statements) insertState(roomNID types.RoomNID, stateDataNIDs []types.St
return return
} }
func (s *statements) bulkSelectStateDataNIDs(stateNIDs []types.StateNID) ([]types.StateDataNIDList, error) { func (s *statements) bulkSelectStateDataNIDs(stateNIDs []types.StateSnapshotNID) ([]types.StateDataNIDList, error) {
nids := make([]int64, len(stateNIDs)) nids := make([]int64, len(stateNIDs))
for i := range stateNIDs { for i := range stateNIDs {
nids[i] = int64(stateNIDs[i]) nids[i] = int64(stateNIDs[i])
@ -645,7 +645,7 @@ func (s *statements) bulkSelectStateDataNIDs(stateNIDs []types.StateNID) ([]type
for ; rows.Next(); i++ { for ; rows.Next(); i++ {
result := &results[i] result := &results[i]
var stateDataNIDs pq.Int64Array var stateDataNIDs pq.Int64Array
if err := rows.Scan(&result.StateNID, &stateDataNIDs); err != nil { if err := rows.Scan(&result.StateSnapshotNID, &stateDataNIDs); err != nil {
return nil, err return nil, err
} }
result.StateDataNIDs = make([]types.StateDataNID, len(stateDataNIDs)) result.StateDataNIDs = make([]types.StateDataNID, len(stateDataNIDs))

View file

@ -44,7 +44,7 @@ func (d *Database) StoreEvent(event gomatrixserverlib.Event, authEventNIDs []typ
eventTypeNID types.EventTypeNID eventTypeNID types.EventTypeNID
eventStateKeyNID types.EventStateKeyNID eventStateKeyNID types.EventStateKeyNID
eventNID types.EventNID eventNID types.EventNID
stateNID types.StateNID stateNID types.StateSnapshotNID
err error err error
) )
@ -81,7 +81,7 @@ func (d *Database) StoreEvent(event gomatrixserverlib.Event, authEventNIDs []typ
} }
return roomNID, types.StateAtEvent{ return roomNID, types.StateAtEvent{
BeforeStateNID: stateNID, BeforeStateSnapshotNID: stateNID,
StateEntry: types.StateEntry{ StateEntry: types.StateEntry{
StateKeyTuple: types.StateKeyTuple{ StateKeyTuple: types.StateKeyTuple{
EventTypeNID: eventTypeNID, EventTypeNID: eventTypeNID,
@ -161,7 +161,7 @@ func (d *Database) Events(eventNIDs []types.EventNID) ([]types.Event, error) {
} }
// AddState implements input.EventDatabase // AddState implements input.EventDatabase
func (d *Database) AddState(roomNID types.RoomNID, stateDataNIDs []types.StateDataNID, state []types.StateEntry) (types.StateNID, error) { func (d *Database) AddState(roomNID types.RoomNID, stateDataNIDs []types.StateDataNID, state []types.StateEntry) (types.StateSnapshotNID, error) {
if len(state) > 0 { if len(state) > 0 {
stateDataNID, err := d.statements.selectNextStateDataNID() stateDataNID, err := d.statements.selectNextStateDataNID()
if err != nil { if err != nil {
@ -177,7 +177,7 @@ func (d *Database) AddState(roomNID types.RoomNID, stateDataNIDs []types.StateDa
} }
// SetState implements input.EventDatabase // SetState implements input.EventDatabase
func (d *Database) SetState(eventNID types.EventNID, stateNID types.StateNID) error { func (d *Database) SetState(eventNID types.EventNID, stateNID types.StateSnapshotNID) error {
return d.statements.updateEventState(eventNID, stateNID) return d.statements.updateEventState(eventNID, stateNID)
} }
@ -187,7 +187,7 @@ func (d *Database) StateAtEventIDs(eventIDs []string) ([]types.StateAtEvent, err
} }
// StateDataNIDs implements input.EventDatabase // StateDataNIDs implements input.EventDatabase
func (d *Database) StateDataNIDs(stateNIDs []types.StateNID) ([]types.StateDataNIDList, error) { func (d *Database) StateDataNIDs(stateNIDs []types.StateSnapshotNID) ([]types.StateDataNIDList, error) {
return d.statements.bulkSelectStateDataNIDs(stateNIDs) return d.statements.bulkSelectStateDataNIDs(stateNIDs)
} }

View file

@ -25,8 +25,8 @@ type EventNID int64
// RoomNID is a numeric ID for a room. // RoomNID is a numeric ID for a room.
type RoomNID int64 type RoomNID int64
// StateNID is a numeric ID for the state at an event. // StateSnapshotNID is a numeric ID for the state at an event.
type StateNID int64 type StateSnapshotNID int64
// StateDataNID is a numeric ID for a block of state data. // StateDataNID is a numeric ID for a block of state data.
// These blocks of state data are combined to form the actual state. // These blocks of state data are combined to form the actual state.
@ -69,7 +69,7 @@ func (a StateEntry) LessThan(b StateEntry) bool {
// StateAtEvent is the state before and after a matrix event. // StateAtEvent is the state before and after a matrix event.
type StateAtEvent struct { type StateAtEvent struct {
// The state before the event. // The state before the event.
BeforeStateNID StateNID BeforeStateSnapshotNID StateSnapshotNID
// The state entry for the event itself, allows us to calculate the state after the event. // The state entry for the event itself, allows us to calculate the state after the event.
StateEntry StateEntry
} }
@ -105,7 +105,7 @@ const (
// StateDataNIDList is used to return the result of bulk StateDataNID lookups from the database. // StateDataNIDList is used to return the result of bulk StateDataNID lookups from the database.
type StateDataNIDList struct { type StateDataNIDList struct {
StateNID StateNID StateSnapshotNID StateSnapshotNID
StateDataNIDs []StateDataNID StateDataNIDs []StateDataNID
} }