mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-24 07:13:09 -06:00
Add graph walking structs
This commit is contained in:
parent
4dc9f3efd4
commit
b8a89731dd
|
|
@ -31,6 +31,8 @@ import (
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const constRelType = "m.reference"
|
||||||
|
|
||||||
type EventRelationshipRequest struct {
|
type EventRelationshipRequest struct {
|
||||||
EventID string `json:"event_id"`
|
EventID string `json:"event_id"`
|
||||||
MaxDepth int `json:"max_depth"`
|
MaxDepth int `json:"max_depth"`
|
||||||
|
|
@ -186,7 +188,7 @@ func includeParent(ctx context.Context, rsAPI roomserver.RoomserverInternalAPI,
|
||||||
// Apply history visibility checks to all these events and add the ones which pass into the response array,
|
// Apply history visibility checks to all these events and add the ones which pass into the response array,
|
||||||
// honouring the recent_first flag and the limit.
|
// honouring the recent_first flag and the limit.
|
||||||
func includeChildren(ctx context.Context, rsAPI roomserver.RoomserverInternalAPI, db Database, parentID string, limit int, recentFirst bool, userID string) ([]*gomatrixserverlib.HeaderedEvent, *util.JSONResponse) {
|
func includeChildren(ctx context.Context, rsAPI roomserver.RoomserverInternalAPI, db Database, parentID string, limit int, recentFirst bool, userID string) ([]*gomatrixserverlib.HeaderedEvent, *util.JSONResponse) {
|
||||||
children, err := db.ChildrenForParent(ctx, parentID, "m.reference", recentFirst)
|
children, err := db.ChildrenForParent(ctx, parentID, constRelType, recentFirst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("failed to get ChildrenForParent")
|
util.GetLogger(ctx).WithError(err).Error("failed to get ChildrenForParent")
|
||||||
resErr := jsonerror.InternalServerError()
|
resErr := jsonerror.InternalServerError()
|
||||||
|
|
@ -216,25 +218,29 @@ func walkThread(
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
var result []*gomatrixserverlib.HeaderedEvent
|
var result []*gomatrixserverlib.HeaderedEvent
|
||||||
eventsToWalk := newWalker(req)
|
eventWalker := walker{
|
||||||
parent, siblingNum, current := eventsToWalk.Next()
|
ctx: ctx,
|
||||||
for current != "" {
|
req: req,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
parent, current := eventWalker.Next()
|
||||||
|
for current.EventID != "" {
|
||||||
// If the response array is >= limit, stop.
|
// If the response array is >= limit, stop.
|
||||||
if len(result) >= limit {
|
if len(result) >= limit {
|
||||||
return result, true
|
return result, true
|
||||||
}
|
}
|
||||||
// If already processed event, skip.
|
// If already processed event, skip.
|
||||||
if included[current] > 0 {
|
if included[current.EventID] > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check how deep the event is compared to event_id, does it exceed (greater than) max_depth? If yes, skip.
|
// Check how deep the event is compared to event_id, does it exceed (greater than) max_depth? If yes, skip.
|
||||||
parentDepth := included[parent]
|
parentDepth := included[parent]
|
||||||
if parentDepth == 0 {
|
if parentDepth == 0 {
|
||||||
util.GetLogger(ctx).Errorf("parent has unknown depth; this should be impossible, parent=%s curr=%s map=%v", parent, current, included)
|
util.GetLogger(ctx).Errorf("parent has unknown depth; this should be impossible, parent=%s curr=%v map=%v", parent, current, included)
|
||||||
// set these at the max to stop walking this part of the DAG
|
// set these at the max to stop walking this part of the DAG
|
||||||
included[parent] = req.MaxDepth
|
included[parent] = req.MaxDepth
|
||||||
included[current] = req.MaxDepth
|
included[current.EventID] = req.MaxDepth
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
depth := parentDepth + 1
|
depth := parentDepth + 1
|
||||||
|
|
@ -243,16 +249,16 @@ func walkThread(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check what number child this event is (ordered by recent_first) compared to its parent, does it exceed (greater than) max_breadth? If yes, skip.
|
// Check what number child this event is (ordered by recent_first) compared to its parent, does it exceed (greater than) max_breadth? If yes, skip.
|
||||||
if siblingNum > req.MaxBreadth {
|
if current.SiblingNumber > req.MaxBreadth {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process the event.
|
// Process the event.
|
||||||
event := getEventIfVisible(ctx, rsAPI, current, userID)
|
event := getEventIfVisible(ctx, rsAPI, current.EventID, userID)
|
||||||
if event != nil {
|
if event != nil {
|
||||||
result = append(result, event)
|
result = append(result, event)
|
||||||
}
|
}
|
||||||
included[current] = depth
|
included[current.EventID] = depth
|
||||||
}
|
}
|
||||||
return result, false
|
return result, false
|
||||||
}
|
}
|
||||||
|
|
@ -291,40 +297,28 @@ func getEventIfVisible(ctx context.Context, rsAPI roomserver.RoomserverInternalA
|
||||||
return &event
|
return &event
|
||||||
}
|
}
|
||||||
|
|
||||||
// walker walks the thread DAG
|
type walkInfo struct {
|
||||||
type walker interface {
|
eventInfo
|
||||||
// Next returns the next event. `current` is the event ID being walked.
|
SiblingNumber int
|
||||||
// `parent` is the parent of `current`. `siblingNum` is the sibling number of `current`, starting
|
|
||||||
// from one.
|
|
||||||
Next() (parent string, siblingNum int, current string)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWalker(req *EventRelationshipRequest) walker {
|
type walker struct {
|
||||||
if *req.DepthFirst {
|
ctx context.Context
|
||||||
return &depthWalker{
|
req *EventRelationshipRequest
|
||||||
req: req,
|
db Database
|
||||||
current: req.EventID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &breadthWalker{req}
|
|
||||||
}
|
|
||||||
|
|
||||||
type depthWalker struct {
|
|
||||||
req *EventRelationshipRequest
|
|
||||||
// db Database
|
|
||||||
current string
|
current string
|
||||||
|
//toProcess []walkInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *depthWalker) Next() (parent string, siblingNum int, current string) {
|
// Next returns the next event to process.
|
||||||
|
func (w *walker) Next() (parent string, current walkInfo) {
|
||||||
//var events []string
|
//var events []string
|
||||||
//children, err := w.db.ChildrenForParent(w.ctx, w.current)
|
|
||||||
return "", 0, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type breadthWalker struct {
|
_, err := w.db.ChildrenForParent(w.ctx, w.current, constRelType, *w.req.RecentFirst)
|
||||||
req *EventRelationshipRequest
|
if err != nil {
|
||||||
}
|
util.GetLogger(w.ctx).WithError(err).Error("Next() failed, cannot walk")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (w *breadthWalker) Next() (parent string, siblingNum int, current string) {
|
return
|
||||||
return "", 0, ""
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue