database: Use an estimator in Cayley's Size() w/ PostgreSQL
This commit is contained in:
parent
f229083e1e
commit
3a1d0602fb
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@ -42,7 +42,7 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "github.com/google/cayley",
|
"ImportPath": "github.com/google/cayley",
|
||||||
"Comment": "v0.4.1-160-gcdf0154",
|
"Comment": "v0.4.1-160-gcdf0154",
|
||||||
"Rev": "cdf0154d1a34019651eb4f46ce666b31f4d8cae7"
|
"Rev": "6027e4c48b3385307bd4bea462149fd544577165"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/julienschmidt/httprouter",
|
"ImportPath": "github.com/julienschmidt/httprouter",
|
||||||
|
@ -21,9 +21,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/barakmich/glog"
|
"github.com/barakmich/glog"
|
||||||
"github.com/coreos/pkg/capnslog"
|
|
||||||
"github.com/coreos/clair/health"
|
"github.com/coreos/clair/health"
|
||||||
"github.com/coreos/clair/utils"
|
"github.com/coreos/clair/utils"
|
||||||
|
"github.com/coreos/pkg/capnslog"
|
||||||
"github.com/google/cayley"
|
"github.com/google/cayley"
|
||||||
"github.com/google/cayley/graph"
|
"github.com/google/cayley/graph"
|
||||||
"github.com/google/cayley/graph/path"
|
"github.com/google/cayley/graph/path"
|
||||||
@ -70,23 +70,29 @@ func Open(dbType, dbPath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
options := make(graph.Options)
|
||||||
|
|
||||||
// Try to create database if necessary
|
switch dbType {
|
||||||
if dbType == "bolt" || dbType == "leveldb" {
|
case "bolt", "leveldb":
|
||||||
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
|
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
|
||||||
// No, initialize it if possible
|
|
||||||
log.Infof("database at %s does not exist yet, creating it", dbPath)
|
log.Infof("database at %s does not exist yet, creating it", dbPath)
|
||||||
|
|
||||||
if err = graph.InitQuadStore(dbType, dbPath, nil); err != nil {
|
err = graph.InitQuadStore(dbType, dbPath, options)
|
||||||
|
if err != nil {
|
||||||
log.Errorf("could not create database at %s : %s", dbPath, err)
|
log.Errorf("could not create database at %s : %s", dbPath, err)
|
||||||
return ErrCantOpen
|
return ErrCantOpen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if dbType == "sql" {
|
case "sql":
|
||||||
graph.InitQuadStore(dbType, dbPath, nil)
|
// Replaces the PostgreSQL's slow COUNT query with a fast estimator.
|
||||||
|
// See:
|
||||||
|
// Ref: https://wiki.postgresql.org/wiki/Count_estimate
|
||||||
|
options["use_estimates"] = true
|
||||||
|
|
||||||
|
graph.InitQuadStore(dbType, dbPath, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
store, err = cayley.NewGraph(dbType, dbPath, nil)
|
store, err = cayley.NewGraph(dbType, dbPath, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("could not open database at %s : %s", dbPath, err)
|
log.Errorf("could not open database at %s : %s", dbPath, err)
|
||||||
return ErrCantOpen
|
return ErrCantOpen
|
||||||
|
19
vendor/github.com/google/cayley/graph/sql/quadstore.go
generated
vendored
19
vendor/github.com/google/cayley/graph/sql/quadstore.go
generated
vendored
@ -42,6 +42,7 @@ type QuadStore struct {
|
|||||||
size int64
|
size int64
|
||||||
lru *cache
|
lru *cache
|
||||||
noSizes bool
|
noSizes bool
|
||||||
|
useEstimates bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func connectSQLTables(addr string, _ graph.Options) (*sql.DB, error) {
|
func connectSQLTables(addr string, _ graph.Options) (*sql.DB, error) {
|
||||||
@ -132,6 +133,11 @@ func newQuadStore(addr string, options graph.Options) (graph.QuadStore, error) {
|
|||||||
qs.noSizes = false
|
qs.noSizes = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
qs.useEstimates, _, err = options.BoolKey("use_estimates")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &qs, nil
|
return &qs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +292,18 @@ func (qs *QuadStore) Size() int64 {
|
|||||||
if qs.size != -1 {
|
if qs.size != -1 {
|
||||||
return qs.size
|
return qs.size
|
||||||
}
|
}
|
||||||
c := qs.db.QueryRow("SELECT COUNT(*) FROM quads;")
|
|
||||||
|
query := "SELECT COUNT(*) FROM quads;"
|
||||||
|
if qs.useEstimates {
|
||||||
|
switch qs.sqlFlavor {
|
||||||
|
case "postgres":
|
||||||
|
query = "SELECT reltuples::BIGINT AS estimate FROM pg_class WHERE relname='quads';"
|
||||||
|
default:
|
||||||
|
panic("no estimate support for flavor: " + qs.sqlFlavor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c := qs.db.QueryRow(query)
|
||||||
err := c.Scan(&qs.size)
|
err := c.Scan(&qs.size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Couldn't execute COUNT: %v", err)
|
glog.Errorf("Couldn't execute COUNT: %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user