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:
4 files changed
+65
-81
No files matched your search
+9
-18
@@ -64,7 +64,7 @@ type SQLQueries interface {
|
|||||||
ListNodesPaginated(ctx context.Context, arg sqlc.ListNodesPaginatedParams) ([]sqlc.Node, error)
|
ListNodesPaginated(ctx context.Context, arg sqlc.ListNodesPaginatedParams) ([]sqlc.Node, error)
|
||||||
ListNodeIDsAndPubKeys(ctx context.Context, arg sqlc.ListNodeIDsAndPubKeysParams) ([]sqlc.ListNodeIDsAndPubKeysRow, error)
|
ListNodeIDsAndPubKeys(ctx context.Context, arg sqlc.ListNodeIDsAndPubKeysParams) ([]sqlc.ListNodeIDsAndPubKeysRow, error)
|
||||||
IsPublicV1Node(ctx context.Context, pubKey []byte) (bool, error)
|
IsPublicV1Node(ctx context.Context, pubKey []byte) (bool, error)
|
||||||
GetUnconnectedNodes(ctx context.Context) ([]sqlc.GetUnconnectedNodesRow, error)
|
DeleteUnconnectedNodes(ctx context.Context) ([][]byte, error)
|
||||||
DeleteNodeByPubKey(ctx context.Context, arg sqlc.DeleteNodeByPubKeyParams) (sql.Result, error)
|
DeleteNodeByPubKey(ctx context.Context, arg sqlc.DeleteNodeByPubKeyParams) (sql.Result, error)
|
||||||
DeleteNode(ctx context.Context, id int64) error
|
DeleteNode(ctx context.Context, id int64) error
|
||||||
|
|
||||||
@@ -2551,30 +2551,21 @@ func (s *SQLStore) PruneTip() (*chainhash.Hash, uint32, error) {
|
|||||||
func (s *SQLStore) pruneGraphNodes(ctx context.Context,
|
func (s *SQLStore) pruneGraphNodes(ctx context.Context,
|
||||||
db SQLQueries) ([]route.Vertex, error) {
|
db SQLQueries) ([]route.Vertex, error) {
|
||||||
|
|
||||||
// Fetch all un-connected nodes from the database.
|
nodeKeys, err := db.DeleteUnconnectedNodes(ctx)
|
||||||
// NOTE: this will not include any nodes that are listed in the
|
|
||||||
// source table.
|
|
||||||
nodes, err := db.GetUnconnectedNodes(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to fetch unconnected nodes: %w",
|
return nil, fmt.Errorf("unable to delete unconnected "+
|
||||||
err)
|
"nodes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prunedNodes := make([]route.Vertex, 0, len(nodes))
|
prunedNodes := make([]route.Vertex, len(nodeKeys))
|
||||||
for _, node := range nodes {
|
for i, nodeKey := range nodeKeys {
|
||||||
// TODO(elle): update to use sqlc.slice() once that works.
|
pub, err := route.NewVertexFromBytes(nodeKey)
|
||||||
if err = db.DeleteNode(ctx, node.ID); err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to delete "+
|
|
||||||
"node(id=%d): %w", node.ID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
pubKey, err := route.NewVertexFromBytes(node.PubKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to parse pubkey "+
|
return nil, fmt.Errorf("unable to parse pubkey "+
|
||||||
"for node(id=%d): %w", node.ID, err)
|
"from bytes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prunedNodes = append(prunedNodes, pubKey)
|
prunedNodes[i] = pub
|
||||||
}
|
}
|
||||||
|
|
||||||
return prunedNodes, nil
|
return prunedNodes, nil
|
||||||
|
|||||||
+40
-45
@@ -244,6 +244,46 @@ func (q *Queries) DeletePruneLogEntriesInRange(ctx context.Context, arg DeletePr
|
|||||||
return err
|
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
|
const deleteZombieChannel = `-- name: DeleteZombieChannel :execresult
|
||||||
DELETE FROM zombie_channels
|
DELETE FROM zombie_channels
|
||||||
WHERE scid = $1
|
WHERE scid = $1
|
||||||
@@ -1388,51 +1428,6 @@ func (q *Queries) GetSourceNodesByVersion(ctx context.Context, version int16) ([
|
|||||||
return items, nil
|
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
|
const getV1DisabledSCIDs = `-- name: GetV1DisabledSCIDs :many
|
||||||
SELECT c.scid
|
SELECT c.scid
|
||||||
FROM channels c
|
FROM channels c
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ type Querier interface {
|
|||||||
DeleteNodeByPubKey(ctx context.Context, arg DeleteNodeByPubKeyParams) (sql.Result, error)
|
DeleteNodeByPubKey(ctx context.Context, arg DeleteNodeByPubKeyParams) (sql.Result, error)
|
||||||
DeleteNodeFeature(ctx context.Context, arg DeleteNodeFeatureParams) error
|
DeleteNodeFeature(ctx context.Context, arg DeleteNodeFeatureParams) error
|
||||||
DeletePruneLogEntriesInRange(ctx context.Context, arg DeletePruneLogEntriesInRangeParams) error
|
DeletePruneLogEntriesInRange(ctx context.Context, arg DeletePruneLogEntriesInRangeParams) error
|
||||||
|
DeleteUnconnectedNodes(ctx context.Context) ([][]byte, error)
|
||||||
DeleteZombieChannel(ctx context.Context, arg DeleteZombieChannelParams) (sql.Result, error)
|
DeleteZombieChannel(ctx context.Context, arg DeleteZombieChannelParams) (sql.Result, error)
|
||||||
FetchAMPSubInvoiceHTLCs(ctx context.Context, arg FetchAMPSubInvoiceHTLCsParams) ([]FetchAMPSubInvoiceHTLCsRow, error)
|
FetchAMPSubInvoiceHTLCs(ctx context.Context, arg FetchAMPSubInvoiceHTLCsParams) ([]FetchAMPSubInvoiceHTLCsRow, error)
|
||||||
FetchAMPSubInvoices(ctx context.Context, arg FetchAMPSubInvoicesParams) ([]AmpSubInvoice, error)
|
FetchAMPSubInvoices(ctx context.Context, arg FetchAMPSubInvoicesParams) ([]AmpSubInvoice, error)
|
||||||
@@ -66,9 +67,6 @@ type Querier interface {
|
|||||||
GetPublicV1ChannelsBySCID(ctx context.Context, arg GetPublicV1ChannelsBySCIDParams) ([]Channel, error)
|
GetPublicV1ChannelsBySCID(ctx context.Context, arg GetPublicV1ChannelsBySCIDParams) ([]Channel, error)
|
||||||
GetSCIDByOutpoint(ctx context.Context, arg GetSCIDByOutpointParams) ([]byte, error)
|
GetSCIDByOutpoint(ctx context.Context, arg GetSCIDByOutpointParams) ([]byte, error)
|
||||||
GetSourceNodesByVersion(ctx context.Context, version int16) ([]GetSourceNodesByVersionRow, 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
|
// NOTE: this is V1 specific since for V1, disabled is a
|
||||||
// simple, single boolean. The proposed V2 policy
|
// simple, single boolean. The proposed V2 policy
|
||||||
// structure will have a more complex disabled bit vector
|
// structure will have a more complex disabled bit vector
|
||||||
|
|||||||
@@ -65,21 +65,21 @@ SELECT EXISTS (
|
|||||||
AND n.pub_key = $1
|
AND n.pub_key = $1
|
||||||
);
|
);
|
||||||
|
|
||||||
-- name: GetUnconnectedNodes :many
|
-- name: DeleteUnconnectedNodes :many
|
||||||
SELECT n.id, n.pub_key
|
DELETE FROM nodes
|
||||||
FROM nodes n
|
WHERE
|
||||||
-- Select all nodes that do not have any channels.
|
-- Ignore any of our source nodes.
|
||||||
WHERE NOT EXISTS (
|
NOT EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM channels c
|
FROM source_nodes sn
|
||||||
WHERE c.node_id_1 = n.id OR c.node_id_2 = n.id
|
WHERE sn.node_id = nodes.id
|
||||||
)
|
)
|
||||||
-- Ignore any of our source nodes.
|
-- Select all nodes that do not have any channels.
|
||||||
AND NOT EXISTS (
|
AND NOT EXISTS (
|
||||||
SELECT 1
|
SELECT 1
|
||||||
FROM source_nodes sn
|
FROM channels c
|
||||||
WHERE sn.node_id = n.id
|
WHERE c.node_id_1 = nodes.id OR c.node_id_2 = nodes.id
|
||||||
);
|
) RETURNING pub_key;
|
||||||
|
|
||||||
-- name: DeleteNodeByPubKey :execresult
|
-- name: DeleteNodeByPubKey :execresult
|
||||||
DELETE FROM nodes
|
DELETE FROM nodes
|
||||||
|
|||||||
Reference in new issue
Block a user