mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
add cache persistence
This commit adds the ability of the Fragment to flush the cache bitmap IDs to disk periodically. They can then be reloaded when the fragment is reopened.
This commit is contained in:
parent
5e11c4c746
commit
b28e961f2e
7 changed files with 354 additions and 62 deletions
12
Godeps/Godeps.json
generated
12
Godeps/Godeps.json
generated
|
|
@ -10,13 +10,19 @@
|
|||
"Comment": "v0.1.0-21-g056c9bc",
|
||||
"Rev": "056c9bc7be7190eaa7715723883caffa5f8fa3e4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/boltdb/bolt",
|
||||
"Comment": "v1.1.0-65-gee4a088",
|
||||
"Rev": "ee4a0888a9abe7eefe5a0992ca4cb06864839873"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Rev": "e762b3d1320b76030bd7f6cc2bfc3d9acce874c0"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gogo/protobuf/proto",
|
||||
"Rev": "499788908625f4d83de42a204d1350fde8588e4f"
|
||||
"Comment": "v0.1-125-g82d16f7",
|
||||
"Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/groupcache/lru",
|
||||
|
|
@ -25,6 +31,10 @@
|
|||
{
|
||||
"ImportPath": "github.com/yasushi-saito/rbtree",
|
||||
"Rev": "571e2538414bf914c7e2909b61217b4e3e5508f4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys/unix",
|
||||
"Rev": "50c6bc5e4292a1d4e65c6e9be5f53be28bcbe28e"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
34
cache.go
34
cache.go
|
|
@ -16,6 +16,9 @@ type Cache interface {
|
|||
Get(bitmapID uint64) *Bitmap
|
||||
Len() int
|
||||
|
||||
// Returns a list of all bitmap IDs.
|
||||
BitmapIDs() []uint64
|
||||
|
||||
// Updates the cache, if necessary.
|
||||
Invalidate()
|
||||
|
||||
|
|
@ -39,7 +42,7 @@ func NewLRUCache(maxEntries int) *LRUCache {
|
|||
return c
|
||||
}
|
||||
|
||||
// Get returns a bitmap with a given id.
|
||||
// Add adds a bitmap to the cache.
|
||||
func (c *LRUCache) Add(bitmapID uint64, bm *Bitmap) {
|
||||
c.cache.Add(bitmapID, bm)
|
||||
c.bitmaps[bitmapID] = bm
|
||||
|
|
@ -60,6 +63,16 @@ func (c *LRUCache) Len() int { return c.cache.Len() }
|
|||
// Invalidate is a no-op.
|
||||
func (c *LRUCache) Invalidate() {}
|
||||
|
||||
// BitmapIDs returns a list of all bitmap IDs in the cache.
|
||||
func (c *LRUCache) BitmapIDs() []uint64 {
|
||||
a := make([]uint64, 0, len(c.bitmaps))
|
||||
for id := range c.bitmaps {
|
||||
a = append(a, id)
|
||||
}
|
||||
sort.Sort(uint64Slice(a))
|
||||
return a
|
||||
}
|
||||
|
||||
// Top returns all bitmaps in the cache.
|
||||
func (c *LRUCache) Top() []BitmapPair {
|
||||
a := make([]BitmapPair, 0, len(c.bitmaps))
|
||||
|
|
@ -98,7 +111,7 @@ func NewRankCache() *RankCache {
|
|||
}
|
||||
}
|
||||
|
||||
// Get returns a bitmap with a given id.
|
||||
// Add adds a bitmap to the cache.
|
||||
func (c *RankCache) Add(bitmapID uint64, bm *Bitmap) {
|
||||
// Ignore if the bit count on the bitmap is below the threshold.
|
||||
if bm.Count() < c.ThresholdValue {
|
||||
|
|
@ -125,6 +138,16 @@ func (c *RankCache) Get(bitmapID uint64) *Bitmap { return c.entries[bitmapID] }
|
|||
// Len returns the number of items in the cache.
|
||||
func (c *RankCache) Len() int { return len(c.entries) }
|
||||
|
||||
// BitmapIDs returns a list of all bitmap IDs in the cache.
|
||||
func (c *RankCache) BitmapIDs() []uint64 {
|
||||
a := make([]uint64, 0, len(c.entries))
|
||||
for id := range c.entries {
|
||||
a = append(a, id)
|
||||
}
|
||||
sort.Sort(uint64Slice(a))
|
||||
return a
|
||||
}
|
||||
|
||||
// Invalidate reorders the entries, if necessary.
|
||||
func (c *RankCache) Invalidate() {
|
||||
// Update if there aren't many items or it hasn't been updated recently.
|
||||
|
|
@ -247,3 +270,10 @@ func decodePairs(a []*internal.Pair) []Pair {
|
|||
}
|
||||
return other
|
||||
}
|
||||
|
||||
// uint64Slice represents a sortable slice of uint64 numbers.
|
||||
type uint64Slice []uint64
|
||||
|
||||
func (p uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
func (p uint64Slice) Len() int { return len(p) }
|
||||
func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"runtime/pprof"
|
||||
|
|
@ -55,8 +56,18 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Wait indefinitely.
|
||||
<-(chan struct{})(nil)
|
||||
// First SIGKILL causes server to shut down gracefully.
|
||||
// Second signal causes a hard shutdown.
|
||||
c := make(chan os.Signal, 2)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
sig := <-c
|
||||
fmt.Fprintf(m.Stderr, "Received %s; gracefully shutting down...\n", sig.String())
|
||||
go func() { <-c; os.Exit(1) }()
|
||||
|
||||
if err := m.Close(); err != nil {
|
||||
fmt.Fprintln(m.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Main represents the main program execution.
|
||||
|
|
|
|||
191
fragment.go
191
fragment.go
|
|
@ -3,6 +3,9 @@ package pilosa
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
|
@ -11,16 +14,28 @@ import (
|
|||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/umbel/pilosa/internal"
|
||||
"github.com/umbel/pilosa/roaring"
|
||||
)
|
||||
|
||||
// SliceWidth is the number of profile IDs in a slice.
|
||||
const SliceWidth = 65536
|
||||
const (
|
||||
// SliceWidth is the number of profile IDs in a slice.
|
||||
SliceWidth = 65536
|
||||
|
||||
// SnapshotExt is the file extension used for an in-process snapshot.
|
||||
const SnapshotExt = ".snapshotting"
|
||||
// SnapshotExt is the file extension used for an in-process snapshot.
|
||||
SnapshotExt = ".snapshotting"
|
||||
|
||||
const MinThreshold = 10
|
||||
// CacheExt is the file extension for persisted cache ids.
|
||||
CacheExt = ".cache"
|
||||
|
||||
MinThreshold = 10
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultCacheFlushInterval is the default value for Fragment.CacheFlushInterval.
|
||||
DefaultCacheFlushInterval = 1 * time.Minute
|
||||
)
|
||||
|
||||
// Fragment represents the intersection of a frame and slice in a database.
|
||||
type Fragment struct {
|
||||
|
|
@ -40,6 +55,16 @@ type Fragment struct {
|
|||
// Bitmap cache.
|
||||
cache Cache
|
||||
|
||||
// Close management
|
||||
wg sync.WaitGroup
|
||||
closing chan struct{}
|
||||
|
||||
// The interval at which the cached bitmap ids are persisted to disk.
|
||||
CacheFlushInterval time.Duration
|
||||
|
||||
// Writer used for out-of-band log entries.
|
||||
LogOutput io.Writer
|
||||
|
||||
// Bitmap attribute storage.
|
||||
// Typically this is the parent frame unless overridden for testing.
|
||||
BitmapAttrStore interface {
|
||||
|
|
@ -49,29 +74,24 @@ type Fragment struct {
|
|||
|
||||
// NewFragment returns a new instance of Fragment.
|
||||
func NewFragment(path, db, frame string, slice uint64) *Fragment {
|
||||
f := &Fragment{
|
||||
path: path,
|
||||
db: db,
|
||||
frame: frame,
|
||||
slice: slice,
|
||||
}
|
||||
return &Fragment{
|
||||
path: path,
|
||||
db: db,
|
||||
frame: frame,
|
||||
slice: slice,
|
||||
closing: make(chan struct{}, 0),
|
||||
|
||||
// Determine cache type from frame name.
|
||||
if strings.HasSuffix(frame, ".n") {
|
||||
c := NewRankCache()
|
||||
c.ThresholdLength = 50000
|
||||
c.ThresholdIndex = 45000
|
||||
f.cache = c
|
||||
} else {
|
||||
f.cache = NewLRUCache(50000)
|
||||
LogOutput: os.Stderr,
|
||||
CacheFlushInterval: DefaultCacheFlushInterval,
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// Path returns the path the fragment was initialized with.
|
||||
func (f *Fragment) Path() string { return f.path }
|
||||
|
||||
// CachePath returns the path to the fragment's cache data.
|
||||
func (f *Fragment) CachePath() string { return f.path + CacheExt }
|
||||
|
||||
// DB returns the database the fragment was initialized with.
|
||||
func (f *Fragment) DB() string { return f.db }
|
||||
|
||||
|
|
@ -81,13 +101,28 @@ func (f *Fragment) Frame() string { return f.frame }
|
|||
// Slice returns the slice the fragment was initialized with.
|
||||
func (f *Fragment) Slice() uint64 { return f.slice }
|
||||
|
||||
// Cache returns the fragment's cache.
|
||||
// This is not safe for concurrent use.
|
||||
func (f *Fragment) Cache() Cache { return f.cache }
|
||||
|
||||
// Open opens the underlying storage.
|
||||
func (f *Fragment) Open() error {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
// Initialize storage in a function so we can close if anything goes wrong.
|
||||
if err := f.openStorage(); err != nil {
|
||||
if err := func() error {
|
||||
// Initialize storage in a function so we can close if anything goes wrong.
|
||||
if err := f.openStorage(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Fill cache with bitmaps persisted to disk.
|
||||
if err := f.openCache(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}(); err != nil {
|
||||
f.close()
|
||||
return err
|
||||
}
|
||||
|
|
@ -152,6 +187,47 @@ func (f *Fragment) openStorage() error {
|
|||
|
||||
}
|
||||
|
||||
// openCache initializes the cache from bitmap ids persisted to disk.
|
||||
func (f *Fragment) openCache() error {
|
||||
// Determine cache type from frame name.
|
||||
if strings.HasSuffix(f.frame, ".n") {
|
||||
c := NewRankCache()
|
||||
c.ThresholdLength = 50000
|
||||
c.ThresholdIndex = 45000
|
||||
f.cache = c
|
||||
} else {
|
||||
f.cache = NewLRUCache(50000)
|
||||
}
|
||||
|
||||
// Read cache data from disk.
|
||||
path := f.CachePath()
|
||||
buf, err := ioutil.ReadFile(path)
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("open cache: %s", err)
|
||||
}
|
||||
|
||||
// Unmarshal cache data.
|
||||
var pb internal.Cache
|
||||
if err := proto.Unmarshal(buf, &pb); err != nil {
|
||||
log.Printf("error unmarshaling cache data, skipping: path=%s, err=%s", path, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read in all bitmaps by ID.
|
||||
// This will cause them to be added to the cache.
|
||||
for _, bitmapID := range pb.GetBitmapIDs() {
|
||||
f.bitmap(bitmapID)
|
||||
}
|
||||
|
||||
// Periodically flush cache.
|
||||
f.wg.Add(1)
|
||||
go func() { defer f.wg.Done(); f.monitorCacheFlush() }()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close flushes the underlying storage, closes the file and unlocks it.
|
||||
func (f *Fragment) Close() error {
|
||||
f.mu.Lock()
|
||||
|
|
@ -160,9 +236,22 @@ func (f *Fragment) Close() error {
|
|||
}
|
||||
|
||||
func (f *Fragment) close() error {
|
||||
if err := f.closeStorage(); err != nil {
|
||||
return err
|
||||
// Notify goroutines of closing and wait for completion.
|
||||
close(f.closing)
|
||||
f.mu.Unlock()
|
||||
f.wg.Wait()
|
||||
f.mu.Lock()
|
||||
|
||||
// Flush cache if closing gracefully.
|
||||
if err := f.flushCache(); err != nil {
|
||||
f.logger().Printf("error flushing cache on close: err=%s, path=%s", err, f.path)
|
||||
}
|
||||
|
||||
// Close underlying storage.
|
||||
if err := f.closeStorage(); err != nil {
|
||||
f.logger().Printf("error closing storage: err=%s, path=%s", err, f.path)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -194,6 +283,9 @@ func (f *Fragment) closeStorage() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// logger returns a logger instance for the fragment.nt.
|
||||
func (f *Fragment) logger() *log.Logger { return log.New(f.LogOutput, "", log.LstdFlags) }
|
||||
|
||||
// Bitmap returns a bitmap by ID.
|
||||
func (f *Fragment) Bitmap(bitmapID uint64) *Bitmap {
|
||||
f.mu.Lock()
|
||||
|
|
@ -479,6 +571,55 @@ func (f *Fragment) snapshot() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// monitorCacheFlush periodically flushes the cache to disk.
|
||||
// This is run in a goroutine.
|
||||
func (f *Fragment) monitorCacheFlush() {
|
||||
ticker := time.NewTicker(f.CacheFlushInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-f.closing:
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := f.FlushCache(); err != nil {
|
||||
f.logger().Printf("error flushing cache: err=%s, path=%s", err, f.CachePath())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FlushCache writes the cache data to disk.
|
||||
func (f *Fragment) FlushCache() error {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
return f.flushCache()
|
||||
}
|
||||
|
||||
func (f *Fragment) flushCache() error {
|
||||
if f.cache == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Retrieve a list of bitmap ids from the cache.
|
||||
bitmapIDs := f.cache.BitmapIDs()
|
||||
|
||||
// Marshal cache data to bytes.
|
||||
buf, err := proto.Marshal(&internal.Cache{
|
||||
BitmapIDs: bitmapIDs,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write to disk.
|
||||
if err := ioutil.WriteFile(f.CachePath(), buf, 0666); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func madvise(b []byte, advice int) (err error) {
|
||||
_, _, e1 := syscall.Syscall(syscall.SYS_MADVISE, uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), uintptr(advice))
|
||||
if e1 != 0 {
|
||||
|
|
|
|||
|
|
@ -211,6 +211,70 @@ func TestFragment_TopN_Intersect_Large(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ensure a fragment's cache can be persisted between restarts.
|
||||
func TestFragment_LRUCache_Persistence(t *testing.T) {
|
||||
f := MustOpenFragment("d", "f", 0)
|
||||
defer f.Close()
|
||||
|
||||
// Set bits on the fragment.
|
||||
for i := uint64(0); i < 1000; i++ {
|
||||
if err := f.SetBit(i, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify correct cache type and size.
|
||||
if cache, ok := f.Cache().(*pilosa.LRUCache); !ok {
|
||||
t.Fatalf("unexpected cache: %T", f.Cache())
|
||||
} else if cache.Len() != 1000 {
|
||||
t.Fatalf("unexpected cache len: %d", cache.Len())
|
||||
}
|
||||
|
||||
// Reopen the fragment.
|
||||
if err := f.Reopen(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Re-verify correct cache type and size.
|
||||
if cache, ok := f.Cache().(*pilosa.LRUCache); !ok {
|
||||
t.Fatalf("unexpected cache: %T", f.Cache())
|
||||
} else if cache.Len() != 1000 {
|
||||
t.Fatalf("unexpected cache len: %d", cache.Len())
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure a fragment's cache can be persisted between restarts.
|
||||
func TestFragment_RankCache_Persistence(t *testing.T) {
|
||||
f := MustOpenFragment("d", "f.n", 0)
|
||||
defer f.Close()
|
||||
|
||||
// Set bits on the fragment.
|
||||
for i := uint64(0); i < 1000; i++ {
|
||||
if err := f.SetBit(i, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify correct cache type and size.
|
||||
if cache, ok := f.Cache().(*pilosa.RankCache); !ok {
|
||||
t.Fatalf("unexpected cache: %T", f.Cache())
|
||||
} else if cache.Len() != 1000 {
|
||||
t.Fatalf("unexpected cache len: %d", cache.Len())
|
||||
}
|
||||
|
||||
// Reopen the fragment.
|
||||
if err := f.Reopen(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Re-verify correct cache type and size.
|
||||
if cache, ok := f.Cache().(*pilosa.RankCache); !ok {
|
||||
t.Fatalf("unexpected cache: %T", f.Cache())
|
||||
} else if cache.Len() != 1000 {
|
||||
t.Fatalf("unexpected cache len: %d", cache.Len())
|
||||
}
|
||||
}
|
||||
|
||||
// Fragment is a test wrapper for pilosa.Fragment.
|
||||
type Fragment struct {
|
||||
*pilosa.Fragment
|
||||
|
|
@ -245,17 +309,19 @@ func MustOpenFragment(db, frame string, slice uint64) *Fragment {
|
|||
// Close closes the fragment and removes all underlying data.
|
||||
func (f *Fragment) Close() error {
|
||||
defer os.Remove(f.Path())
|
||||
defer os.Remove(f.CachePath())
|
||||
return f.Fragment.Close()
|
||||
}
|
||||
|
||||
// Reopen closes the fragment and reopens it as a new instance.
|
||||
func (f *Fragment) Reopen() error {
|
||||
path := f.Path()
|
||||
if err := f.Close(); err != nil {
|
||||
if err := f.Fragment.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f = &Fragment{Fragment: pilosa.NewFragment(path, f.DB(), f.Frame(), f.Slice())}
|
||||
f.Fragment = pilosa.NewFragment(path, f.DB(), f.Frame(), f.Slice())
|
||||
f.Fragment.BitmapAttrStore = f.BitmapAttrStore
|
||||
if err := f.Open(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,19 +19,22 @@ It has these top-level messages:
|
|||
QueryResponse
|
||||
ImportRequest
|
||||
ImportResponse
|
||||
Cache
|
||||
*/
|
||||
package internal
|
||||
|
||||
import proto "github.com/gogo/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
type Bitmap struct {
|
||||
Chunks []*Chunk `protobuf:"bytes,1,rep" json:"Chunks,omitempty"`
|
||||
Attrs []*Attr `protobuf:"bytes,2,rep" json:"Attrs,omitempty"`
|
||||
Chunks []*Chunk `protobuf:"bytes,1,rep,name=Chunks" json:"Chunks,omitempty"`
|
||||
Attrs []*Attr `protobuf:"bytes,2,rep,name=Attrs" json:"Attrs,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -54,8 +57,8 @@ func (m *Bitmap) GetAttrs() []*Attr {
|
|||
}
|
||||
|
||||
type Chunk struct {
|
||||
Key *uint64 `protobuf:"varint,1,req" json:"Key,omitempty"`
|
||||
Value []uint64 `protobuf:"varint,2,rep" json:"Value,omitempty"`
|
||||
Key *uint64 `protobuf:"varint,1,req,name=Key" json:"Key,omitempty"`
|
||||
Value []uint64 `protobuf:"varint,2,rep,name=Value" json:"Value,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -78,8 +81,8 @@ func (m *Chunk) GetValue() []uint64 {
|
|||
}
|
||||
|
||||
type Pair struct {
|
||||
Key *uint64 `protobuf:"varint,1,req" json:"Key,omitempty"`
|
||||
Count *uint64 `protobuf:"varint,2,req" json:"Count,omitempty"`
|
||||
Key *uint64 `protobuf:"varint,1,req,name=Key" json:"Key,omitempty"`
|
||||
Count *uint64 `protobuf:"varint,2,req,name=Count" json:"Count,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -102,8 +105,8 @@ func (m *Pair) GetCount() uint64 {
|
|||
}
|
||||
|
||||
type Bit struct {
|
||||
BitmapID *uint64 `protobuf:"varint,1,req" json:"BitmapID,omitempty"`
|
||||
ProfileID *uint64 `protobuf:"varint,2,req" json:"ProfileID,omitempty"`
|
||||
BitmapID *uint64 `protobuf:"varint,1,req,name=BitmapID" json:"BitmapID,omitempty"`
|
||||
ProfileID *uint64 `protobuf:"varint,2,req,name=ProfileID" json:"ProfileID,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -126,8 +129,8 @@ func (m *Bit) GetProfileID() uint64 {
|
|||
}
|
||||
|
||||
type Profile struct {
|
||||
ID *uint64 `protobuf:"varint,1,req" json:"ID,omitempty"`
|
||||
Attrs []*Attr `protobuf:"bytes,2,rep" json:"Attrs,omitempty"`
|
||||
ID *uint64 `protobuf:"varint,1,req,name=ID" json:"ID,omitempty"`
|
||||
Attrs []*Attr `protobuf:"bytes,2,rep,name=Attrs" json:"Attrs,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -150,10 +153,10 @@ func (m *Profile) GetAttrs() []*Attr {
|
|||
}
|
||||
|
||||
type Attr struct {
|
||||
Key *string `protobuf:"bytes,1,req" json:"Key,omitempty"`
|
||||
StringValue *string `protobuf:"bytes,2,opt" json:"StringValue,omitempty"`
|
||||
IntValue *int64 `protobuf:"varint,3,opt" json:"IntValue,omitempty"`
|
||||
BoolValue *bool `protobuf:"varint,4,opt" json:"BoolValue,omitempty"`
|
||||
Key *string `protobuf:"bytes,1,req,name=Key" json:"Key,omitempty"`
|
||||
StringValue *string `protobuf:"bytes,2,opt,name=StringValue" json:"StringValue,omitempty"`
|
||||
IntValue *int64 `protobuf:"varint,3,opt,name=IntValue" json:"IntValue,omitempty"`
|
||||
BoolValue *bool `protobuf:"varint,4,opt,name=BoolValue" json:"BoolValue,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -190,10 +193,10 @@ func (m *Attr) GetBoolValue() bool {
|
|||
}
|
||||
|
||||
type QueryRequest struct {
|
||||
DB *string `protobuf:"bytes,1,req" json:"DB,omitempty"`
|
||||
Query *string `protobuf:"bytes,2,req" json:"Query,omitempty"`
|
||||
Slices []uint64 `protobuf:"varint,3,rep" json:"Slices,omitempty"`
|
||||
Profiles *bool `protobuf:"varint,4,opt" json:"Profiles,omitempty"`
|
||||
DB *string `protobuf:"bytes,1,req,name=DB" json:"DB,omitempty"`
|
||||
Query *string `protobuf:"bytes,2,req,name=Query" json:"Query,omitempty"`
|
||||
Slices []uint64 `protobuf:"varint,3,rep,name=Slices" json:"Slices,omitempty"`
|
||||
Profiles *bool `protobuf:"varint,4,opt,name=Profiles" json:"Profiles,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -230,11 +233,11 @@ func (m *QueryRequest) GetProfiles() bool {
|
|||
}
|
||||
|
||||
type QueryResponse struct {
|
||||
Err *string `protobuf:"bytes,1,opt" json:"Err,omitempty"`
|
||||
Bitmap *Bitmap `protobuf:"bytes,2,opt" json:"Bitmap,omitempty"`
|
||||
N *uint64 `protobuf:"varint,3,opt" json:"N,omitempty"`
|
||||
Pairs []*Pair `protobuf:"bytes,4,rep" json:"Pairs,omitempty"`
|
||||
Profiles []*Profile `protobuf:"bytes,5,rep" json:"Profiles,omitempty"`
|
||||
Err *string `protobuf:"bytes,1,opt,name=Err" json:"Err,omitempty"`
|
||||
Bitmap *Bitmap `protobuf:"bytes,2,opt,name=Bitmap" json:"Bitmap,omitempty"`
|
||||
N *uint64 `protobuf:"varint,3,opt,name=N" json:"N,omitempty"`
|
||||
Pairs []*Pair `protobuf:"bytes,4,rep,name=Pairs" json:"Pairs,omitempty"`
|
||||
Profiles []*Profile `protobuf:"bytes,5,rep,name=Profiles" json:"Profiles,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -278,11 +281,11 @@ func (m *QueryResponse) GetProfiles() []*Profile {
|
|||
}
|
||||
|
||||
type ImportRequest struct {
|
||||
DB *string `protobuf:"bytes,1,req" json:"DB,omitempty"`
|
||||
Frame *string `protobuf:"bytes,2,req" json:"Frame,omitempty"`
|
||||
Slice *uint64 `protobuf:"varint,3,req" json:"Slice,omitempty"`
|
||||
BitmapIDs []uint64 `protobuf:"varint,4,rep" json:"BitmapIDs,omitempty"`
|
||||
ProfileIDs []uint64 `protobuf:"varint,5,rep" json:"ProfileIDs,omitempty"`
|
||||
DB *string `protobuf:"bytes,1,req,name=DB" json:"DB,omitempty"`
|
||||
Frame *string `protobuf:"bytes,2,req,name=Frame" json:"Frame,omitempty"`
|
||||
Slice *uint64 `protobuf:"varint,3,req,name=Slice" json:"Slice,omitempty"`
|
||||
BitmapIDs []uint64 `protobuf:"varint,4,rep,name=BitmapIDs" json:"BitmapIDs,omitempty"`
|
||||
ProfileIDs []uint64 `protobuf:"varint,5,rep,name=ProfileIDs" json:"ProfileIDs,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -326,7 +329,7 @@ func (m *ImportRequest) GetProfileIDs() []uint64 {
|
|||
}
|
||||
|
||||
type ImportResponse struct {
|
||||
Err *string `protobuf:"bytes,1,opt" json:"Err,omitempty"`
|
||||
Err *string `protobuf:"bytes,1,opt,name=Err" json:"Err,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
|
|
@ -341,5 +344,32 @@ func (m *ImportResponse) GetErr() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
type Cache struct {
|
||||
BitmapIDs []uint64 `protobuf:"varint,1,rep,name=BitmapIDs" json:"BitmapIDs,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Cache) Reset() { *m = Cache{} }
|
||||
func (m *Cache) String() string { return proto.CompactTextString(m) }
|
||||
func (*Cache) ProtoMessage() {}
|
||||
|
||||
func (m *Cache) GetBitmapIDs() []uint64 {
|
||||
if m != nil {
|
||||
return m.BitmapIDs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Bitmap)(nil), "internal.Bitmap")
|
||||
proto.RegisterType((*Chunk)(nil), "internal.Chunk")
|
||||
proto.RegisterType((*Pair)(nil), "internal.Pair")
|
||||
proto.RegisterType((*Bit)(nil), "internal.Bit")
|
||||
proto.RegisterType((*Profile)(nil), "internal.Profile")
|
||||
proto.RegisterType((*Attr)(nil), "internal.Attr")
|
||||
proto.RegisterType((*QueryRequest)(nil), "internal.QueryRequest")
|
||||
proto.RegisterType((*QueryResponse)(nil), "internal.QueryResponse")
|
||||
proto.RegisterType((*ImportRequest)(nil), "internal.ImportRequest")
|
||||
proto.RegisterType((*ImportResponse)(nil), "internal.ImportResponse")
|
||||
proto.RegisterType((*Cache)(nil), "internal.Cache")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,3 +58,7 @@ message ImportRequest {
|
|||
message ImportResponse {
|
||||
optional string Err = 1;
|
||||
}
|
||||
|
||||
message Cache {
|
||||
repeated uint64 BitmapIDs = 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue