sqldb+graph/db: prune graph nodes in a single query

Update the pruneGraphNodes routine to prune the graph nodes in a single
query instead of two.
This commit is contained in:
Elle Mouton
2025-06-26 10:10:10 +02:00
parent 714e528a3a
commit f1b7ccc6b2
4 changed files with 65 additions and 81 deletions

View File

@ -244,6 +244,46 @@ func (q *Queries) DeletePruneLogEntriesInRange(ctx context.Context, arg DeletePr
return err
}
const deleteUnconnectedNodes = `-- name: DeleteUnconnectedNodes :many
DELETE FROM nodes
WHERE
-- Ignore any of our source nodes.
NOT EXISTS (
SELECT 1
FROM source_nodes sn
WHERE sn.node_id = nodes.id
)
-- Select all nodes that do not have any channels.
AND NOT EXISTS (
SELECT 1
FROM channels c
WHERE c.node_id_1 = nodes.id OR c.node_id_2 = nodes.id
) RETURNING pub_key
`
func (q *Queries) DeleteUnconnectedNodes(ctx context.Context) ([][]byte, error) {
rows, err := q.db.QueryContext(ctx, deleteUnconnectedNodes)
if err != nil {
return nil, err
}
defer rows.Close()
var items [][]byte
for rows.Next() {
var pub_key []byte
if err := rows.Scan(&pub_key); err != nil {
return nil, err
}
items = append(items, pub_key)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const deleteZombieChannel = `-- name: DeleteZombieChannel :execresult
DELETE FROM zombie_channels
WHERE scid = $1
@ -1388,51 +1428,6 @@ func (q *Queries) GetSourceNodesByVersion(ctx context.Context, version int16) ([
return items, nil
}
const getUnconnectedNodes = `-- name: GetUnconnectedNodes :many
SELECT n.id, n.pub_key
FROM nodes n
WHERE NOT EXISTS (
SELECT 1
FROM channels c
WHERE c.node_id_1 = n.id OR c.node_id_2 = n.id
)
AND NOT EXISTS (
SELECT 1
FROM source_nodes sn
WHERE sn.node_id = n.id
)
`
type GetUnconnectedNodesRow struct {
ID int64
PubKey []byte
}
// Select all nodes that do not have any channels.
// Ignore any of our source nodes.
func (q *Queries) GetUnconnectedNodes(ctx context.Context) ([]GetUnconnectedNodesRow, error) {
rows, err := q.db.QueryContext(ctx, getUnconnectedNodes)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetUnconnectedNodesRow
for rows.Next() {
var i GetUnconnectedNodesRow
if err := rows.Scan(&i.ID, &i.PubKey); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getV1DisabledSCIDs = `-- name: GetV1DisabledSCIDs :many
SELECT c.scid
FROM channels c

View File

@ -27,6 +27,7 @@ type Querier interface {
DeleteNodeByPubKey(ctx context.Context, arg DeleteNodeByPubKeyParams) (sql.Result, error)
DeleteNodeFeature(ctx context.Context, arg DeleteNodeFeatureParams) error
DeletePruneLogEntriesInRange(ctx context.Context, arg DeletePruneLogEntriesInRangeParams) error
DeleteUnconnectedNodes(ctx context.Context) ([][]byte, error)
DeleteZombieChannel(ctx context.Context, arg DeleteZombieChannelParams) (sql.Result, error)
FetchAMPSubInvoiceHTLCs(ctx context.Context, arg FetchAMPSubInvoiceHTLCsParams) ([]FetchAMPSubInvoiceHTLCsRow, error)
FetchAMPSubInvoices(ctx context.Context, arg FetchAMPSubInvoicesParams) ([]AmpSubInvoice, error)
@ -66,9 +67,6 @@ type Querier interface {
GetPublicV1ChannelsBySCID(ctx context.Context, arg GetPublicV1ChannelsBySCIDParams) ([]Channel, error)
GetSCIDByOutpoint(ctx context.Context, arg GetSCIDByOutpointParams) ([]byte, error)
GetSourceNodesByVersion(ctx context.Context, version int16) ([]GetSourceNodesByVersionRow, error)
// Select all nodes that do not have any channels.
// Ignore any of our source nodes.
GetUnconnectedNodes(ctx context.Context) ([]GetUnconnectedNodesRow, error)
// NOTE: this is V1 specific since for V1, disabled is a
// simple, single boolean. The proposed V2 policy
// structure will have a more complex disabled bit vector

View File

@ -65,21 +65,21 @@ SELECT EXISTS (
AND n.pub_key = $1
);
-- name: GetUnconnectedNodes :many
SELECT n.id, n.pub_key
FROM nodes n
-- Select all nodes that do not have any channels.
WHERE NOT EXISTS (
SELECT 1
FROM channels c
WHERE c.node_id_1 = n.id OR c.node_id_2 = n.id
)
-- Ignore any of our source nodes.
AND NOT EXISTS (
SELECT 1
FROM source_nodes sn
WHERE sn.node_id = n.id
);
-- name: DeleteUnconnectedNodes :many
DELETE FROM nodes
WHERE
-- Ignore any of our source nodes.
NOT EXISTS (
SELECT 1
FROM source_nodes sn
WHERE sn.node_id = nodes.id
)
-- Select all nodes that do not have any channels.
AND NOT EXISTS (
SELECT 1
FROM channels c
WHERE c.node_id_1 = nodes.id OR c.node_id_2 = nodes.id
) RETURNING pub_key;
-- name: DeleteNodeByPubKey :execresult
DELETE FROM nodes