diff --git a/fragment.go b/fragment.go index aaef9323a..88b39663c 100644 --- a/fragment.go +++ b/fragment.go @@ -28,7 +28,8 @@ import ( const ( // SliceWidth is the number of profile IDs in a slice. - SliceWidth = 1048576 + //SliceWidth = 1048576 + SliceWidth = 262144 // SnapshotExt is the file extension used for an in-process snapshot. SnapshotExt = ".snapshotting" @@ -49,8 +50,25 @@ const ( const ( // DefaultFragmentMaxOpN is the default value for Fragment.MaxOpN. - DefaultFragmentMaxOpN = 1000 + //TODO CHANGING FOR TEST TO 10x + DefaultFragmentMaxOpN = 2000 ) +type BitmapCacher interface { + Fetch(id uint64)(*Bitmap,bool) + Add(id uint64, b *Bitmap) +} + + +type Simple struct{ + cache map[uint64]*Bitmap +} +func (s *Simple)Fetch(id uint64)(*Bitmap,bool){ + m,ok:=s.cache[id] + return m,ok +} +func (s *Simple)Add(id uint64,p*Bitmap){ + s.cache[id]=p +} // Fragment represents the intersection of a frame and slice in a database. type Fragment struct { @@ -87,6 +105,8 @@ type Fragment struct { BitmapAttrStore *AttrStore stats StatsClient + turbo BitmapCacher + } // NewFragment returns a new instance of Fragment. @@ -203,6 +223,7 @@ func (f *Fragment) openStorage() error { // Attach the file to the bitmap to act as a write-ahead log. f.storage.OpWriter = f.file + f.turbo = &Simple{make(map[uint64]*Bitmap)} return nil @@ -308,7 +329,12 @@ func (f *Fragment) Bitmap(bitmapID uint64) *Bitmap { return f.bitmap(bitmapID) } + func (f *Fragment) bitmap(bitmapID uint64) *Bitmap { + r,ok:=f.turbo.Fetch(bitmapID) + if ok && r != nil{ + return r + } // Only use a subset of the containers. // NOTE: The start & end ranges must be divisible by data := f.storage.OffsetRange(f.slice*SliceWidth, bitmapID*SliceWidth, (bitmapID+1)*SliceWidth) @@ -325,6 +351,7 @@ func (f *Fragment) bitmap(bitmapID uint64) *Bitmap { // Update cache. f.cache.Add(bitmapID, bm.Count()) + f.turbo.Add(bitmapID, bm) return bm } @@ -918,10 +945,15 @@ func (f *Fragment) Snapshot() error { defer f.mu.Unlock() return f.snapshot() } +func track(start time.Time, name string, logger *log.Logger) { + elapsed := time.Since(start) + logger.Printf("%s took %s", name, elapsed) +} func (f *Fragment) snapshot() error { logger := f.logger() logger.Printf("fragment: snapshotting %s/%s/%d", f.db, f.frame, f.slice) + defer track(time.Now(), fmt.Sprintf("fragment: snapshot complete %s/%s/%d", f.db, f.frame, f.slice), logger) // Create a temporary file to snapshot to. snapshotPath := f.path + SnapshotExt