-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
graph: extract cache from CRUD [2] #9545
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,93 @@ | ||
package graphdb | ||
|
||
import "github.com/lightningnetwork/lnd/kvdb" | ||
import ( | ||
"time" | ||
|
||
"github.com/lightningnetwork/lnd/graph/db/models" | ||
"github.com/lightningnetwork/lnd/kvdb" | ||
"github.com/lightningnetwork/lnd/lnwire" | ||
"github.com/lightningnetwork/lnd/routing/route" | ||
) | ||
|
||
// Config is a struct that holds all the necessary dependencies for a | ||
// ChannelGraph. | ||
type Config struct { | ||
// KVDB is the kvdb.Backend that will be used for initializing the | ||
// KVStore CRUD layer. | ||
KVDB kvdb.Backend | ||
|
||
// KVStoreOpts is a list of functional options that will be used when | ||
// initializing the KVStore. | ||
KVStoreOpts []KVStoreOptionModifier | ||
} | ||
|
||
// ChannelGraph is a layer above the graph's CRUD layer. | ||
// | ||
// NOTE: currently, this is purely a pass-through layer directly to the backing | ||
// KVStore. Upcoming commits will move the graph cache out of the KVStore and | ||
// into this layer so that the KVStore is only responsible for CRUD operations. | ||
type ChannelGraph struct { | ||
graphCache *GraphCache | ||
|
||
*KVStore | ||
} | ||
|
||
// NewChannelGraph creates a new ChannelGraph instance with the given backend. | ||
func NewChannelGraph(db kvdb.Backend, options ...OptionModifier) (*ChannelGraph, | ||
func NewChannelGraph(cfg *Config, options ...ChanGraphOption) (*ChannelGraph, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎉 |
||
error) { | ||
|
||
store, err := NewKVStore(db, options...) | ||
opts := defaultChanGraphOptions() | ||
for _, o := range options { | ||
o(opts) | ||
} | ||
|
||
store, err := NewKVStore(cfg.KVDB, cfg.KVStoreOpts...) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see above comment about Config struct being ChannelGraph config and not KVStore config. We could add a KVStore config struct and then have the COnfig struct hold that struct but i think we can also after this series unexport anything KVStore related anyways so then would probs not make sense to have an exported KVStore config struct |
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if !opts.useGraphCache { | ||
return &ChannelGraph{ | ||
KVStore: store, | ||
}, nil | ||
} | ||
|
||
// The graph cache can be turned off (e.g. for mobile users) for a | ||
// speed/memory usage tradeoff. | ||
graphCache := NewGraphCache(opts.preAllocCacheNumNodes) | ||
startTime := time.Now() | ||
log.Debugf("Populating in-memory channel graph, this might take a " + | ||
"while...") | ||
|
||
err = store.ForEachNodeCacheable(func(node route.Vertex, | ||
features *lnwire.FeatureVector) error { | ||
|
||
graphCache.AddNodeFeatures(node, features) | ||
|
||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = store.ForEachChannel(func(info *models.ChannelEdgeInfo, | ||
policy1, policy2 *models.ChannelEdgePolicy) error { | ||
|
||
graphCache.AddChannel(info, policy1, policy2) | ||
|
||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("Finished populating in-memory channel graph (took %v, %s)", | ||
time.Since(startTime), graphCache.Stats()) | ||
|
||
store.setGraphCache(graphCache) | ||
|
||
return &ChannelGraph{ | ||
KVStore: store, | ||
KVStore: store, | ||
graphCache: graphCache, | ||
}, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -198,7 +198,7 @@ type KVStore struct { | |
|
||
// NewKVStore allocates a new KVStore backed by a DB instance. The | ||
// returned instance has its own unique reject cache and channel cache. | ||
func NewKVStore(db kvdb.Backend, options ...OptionModifier) (*KVStore, | ||
func NewKVStore(db kvdb.Backend, options ...KVStoreOptionModifier) (*KVStore, | ||
error) { | ||
|
||
opts := DefaultOptions() | ||
|
@@ -224,43 +224,18 @@ func NewKVStore(db kvdb.Backend, options ...OptionModifier) (*KVStore, | |
db, nil, opts.BatchCommitInterval, | ||
) | ||
|
||
// The graph cache can be turned off (e.g. for mobile users) for a | ||
// speed/memory usage tradeoff. | ||
if opts.UseGraphCache { | ||
g.graphCache = NewGraphCache(opts.PreAllocCacheNumNodes) | ||
startTime := time.Now() | ||
log.Debugf("Populating in-memory channel graph, this might " + | ||
"take a while...") | ||
|
||
err := g.ForEachNodeCacheable(func(node route.Vertex, | ||
features *lnwire.FeatureVector) error { | ||
|
||
g.graphCache.AddNodeFeatures(node, features) | ||
|
||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = g.ForEachChannel(func(info *models.ChannelEdgeInfo, | ||
policy1, policy2 *models.ChannelEdgePolicy) error { | ||
|
||
g.graphCache.AddChannel(info, policy1, policy2) | ||
|
||
return nil | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("Finished populating in-memory channel graph (took "+ | ||
"%v, %s)", time.Since(startTime), g.graphCache.Stats()) | ||
} | ||
|
||
return g, nil | ||
} | ||
|
||
// setGraphCache sets the KVStore's graphCache. | ||
// | ||
// NOTE: this is temporary and will only be called from the ChannelGraph's | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
// constructor before the KVStore methods are available to be called. This will | ||
// be removed once the graph cache is fully owned by the ChannelGraph. | ||
func (c *KVStore) setGraphCache(cache *GraphCache) { | ||
c.graphCache = cache | ||
} | ||
|
||
// channelMapKey is the key structure used for storing channel edge policies. | ||
type channelMapKey struct { | ||
nodeKey route.Vertex | ||
|
@@ -4827,8 +4802,8 @@ func (c *chanGraphNodeTx) ForEachChannel(f func(*models.ChannelEdgeInfo, | |
|
||
// MakeTestGraph creates a new instance of the KVStore for testing | ||
// purposes. | ||
func MakeTestGraph(t testing.TB, modifiers ...OptionModifier) (*ChannelGraph, | ||
error) { | ||
func MakeTestGraph(t testing.TB, modifiers ...KVStoreOptionModifier) ( | ||
*ChannelGraph, error) { | ||
|
||
opts := DefaultOptions() | ||
for _, modifier := range modifiers { | ||
|
@@ -4843,7 +4818,10 @@ func MakeTestGraph(t testing.TB, modifiers ...OptionModifier) (*ChannelGraph, | |
return nil, err | ||
} | ||
|
||
graph, err := NewChannelGraph(backend) | ||
graph, err := NewChannelGraph(&Config{ | ||
KVDB: backend, | ||
KVStoreOpts: modifiers, | ||
}) | ||
if err != nil { | ||
backendCleanup() | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
KVDBConfig
? No strong opinion here tho, as this is a place I find myself struggling sometimes. It's nice to just name itConfig
, as suggested by the official go, and use it asgraphdb.Config
. But in practice it's easier to search using a unique name.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is the config struct for ChannelGraph and not for the KVStore. It just at the moment happens to only hold KVStore related things but will be expanded in future.