diff --git a/dispatch/dispatch.go b/dispatch/dispatch.go index 59a46473e..fe280cfed 100644 --- a/dispatch/dispatch.go +++ b/dispatch/dispatch.go @@ -37,94 +37,6 @@ func (self *Dispatch) Run() { default: //log.Println("Unprocessed message", data) } - - /* - path := message.Data.(string) - - bits := strings.Split(path, "/") - - var fragment_id util.SUUID - var bitmaps []uint64 - var profile_id uint64 - var s uint64 - - command := bits[0] - if len(bits) > 1 { - fragment_id = util.Hex_to_SUUID(bits[1]) - } - if len(bits) > 2 { - bitmap_ids := strings.Split(bits[2], ",") - spew.Dump(bitmap_ids) - for i := range bitmap_ids { - spew.Dump(i, bitmap_ids[i]) - s, _ = strconv.ParseUint(bitmap_ids[i], 10, 64) - bitmaps = append(bitmaps, s) - } - } - if len(bits) > 3 { - profile_id, _ = strconv.ParseUint(bits[3], 10, 64) - } - - spew.Dump("COMMAND:", command) - spew.Dump("FRAGID:", fragment_id) - spew.Dump("BITMAPS:", bitmaps) - spew.Dump("PROFILEID:", profile_id) - - if command == "set" { - res, err := self.service.Process.SetBit(fragment_id, bitmaps[0], profile_id) - spew.Dump("SET") - spew.Dump(res) - spew.Dump(err) - } - if command == "count" { - spew.Dump("COUNT") - bh, err := self.service.Process.Get(fragment_id, bitmaps[0]) - if err != nil { - spew.Dump(err) - } - count, err := self.service.Process.Count(fragment_id, bh) - if err != nil { - spew.Dump(err) - } - spew.Dump(count) - } - if command == "intersect" { - spew.Dump("INTERSECT") - var bhs []index.BitmapHandle - for i := range bitmaps { - bh, _ := self.service.Process.Get(fragment_id, bitmaps[i]) - bhs = append(bhs, bh) - } - bhi, err := self.service.Process.Intersect(fragment_id, bhs) - if err != nil { - spew.Dump(err) - } - - count, err := self.service.Process.Count(fragment_id, bhi) - if err != nil { - spew.Dump(err) - } - spew.Dump(count) - } - if command == "union" { - spew.Dump("UNION") - var bhs []index.BitmapHandle - for i := range bitmaps { - bh, _ := self.service.Process.Get(fragment_id, bitmaps[i]) - bhs = append(bhs, bh) - } - bhi, err := self.service.Process.Union(fragment_id, bhs) - if err != nil { - spew.Dump(err) - } - - count, err := self.service.Process.Count(fragment_id, bhi) - if err != nil { - spew.Dump(err) - } - spew.Dump(count) - } - */ } } diff --git a/query/planner.go b/query/planner.go index 8f1abf612..09941f202 100644 --- a/query/planner.go +++ b/query/planner.go @@ -18,15 +18,36 @@ type QueryStep struct { destination *db.Location } +func (q QueryStep) StringHOLD() string { + return fmt.Sprintf("%s %s %s, LOC: %s, DEST: %s", q.operation, q.id.String(), q.inputs, q.location, q.destination) +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// COUNT +/////////////////////////////////////////////////////////////////////////////////////////////////// type CountQueryStep struct { - Id *uuid.UUID - Operation string - //Input QueryInput + Id *uuid.UUID + Operation string Input *uuid.UUID Location *db.Location Destination *db.Location } +// QueryTree for COUNT queries +type CountQueryTree struct { + operation string + subquery QueryTree + location *db.Location +} + +// Uses consistent hashing function to select node containing data for GET operation +func (qt *CountQueryTree) getLocation(d *db.Database) *db.Location { + return qt.subquery.getLocation(d) +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// CAT +/////////////////////////////////////////////////////////////////////////////////////////////////// type CatQueryStep struct { Id *uuid.UUID Operation string @@ -44,10 +65,28 @@ func (self CatQueryResult) ResultId() *uuid.UUID { return self.Id } -func init() { - gob.Register(CatQueryResult{}) +// QueryTree for CAT queries +type CatQueryTree struct { + subqueries []QueryTree + location *db.Location } +// Uses consistent hashing function to select node containing data for GET operation +func (qt *CatQueryTree) getLocation(d *db.Database) *db.Location { + if qt.location == nil { + subqueryLength := len(qt.subqueries) + if subqueryLength > 0 { + locationIndex := rand.Intn(subqueryLength) + subquery := qt.subqueries[locationIndex] + qt.location = subquery.getLocation(d) + } + } + return qt.location +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// GET +/////////////////////////////////////////////////////////////////////////////////////////////////// type GetQueryStep struct { Id *uuid.UUID Operation string @@ -64,6 +103,25 @@ func (qs GetQueryStep) LocIsDest() bool { return false } +// QueryTree for GET queries +type GetQueryTree struct { + bitmap *db.Bitmap + slice int +} + +// Uses consistent hashing function to select node containing data for GET operation +func (qt *GetQueryTree) getLocation(d *db.Database) *db.Location { + slice := d.GetOrCreateSlice(qt.slice) // TODO: this should probably be just GetSlice (no create) + fragment, err := d.GetFragmentForBitmap(slice, qt.bitmap) + if err != nil { + panic(err) + } + return fragment.GetLocation() +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// SET +/////////////////////////////////////////////////////////////////////////////////////////////////// type SetQueryStep struct { Id *uuid.UUID Operation string @@ -73,10 +131,30 @@ type SetQueryStep struct { Destination *db.Location } -func (q QueryStep) StringHOLD() string { - return fmt.Sprintf("%s %s %s, LOC: %s, DEST: %s", q.operation, q.id.String(), q.inputs, q.location, q.destination) +// QueryTree for SET queries +type SetQueryTree struct { + bitmap *db.Bitmap + profile_id uint64 } +// Uses consistent hashing function to select node containing data for GET operation +func (qt *SetQueryTree) getLocation(d *db.Database) *db.Location { + slice, err := d.GetSliceForProfile(qt.profile_id) + fragment, err := d.GetFragmentForBitmap(slice, qt.bitmap) + if err != nil { + panic(err) + } + return fragment.GetLocation() +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +func init() { + gob.Register(CatQueryResult{}) +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + // This is the output of the query planner. Contains a list of steps which can be performed in parallel //type QueryPlan []QueryStep type QueryPlan []interface{} @@ -84,7 +162,6 @@ type QueryPlan []interface{} type QueryPlanner struct { Database *db.Database } - type QueryTree interface { getLocation(d *db.Database) *db.Location } @@ -96,13 +173,6 @@ type CompositeQueryTree struct { location *db.Location } -// QueryTree for COUNT queries -type CountQueryTree struct { - operation string - subquery QueryTree - location *db.Location -} - // Randomly select location from subqueries (so subqueries roll up into composite queries while minimizing inter-node data traffic) func (qt *CompositeQueryTree) getLocation(d *db.Database) *db.Location { if qt.location == nil { @@ -116,64 +186,6 @@ func (qt *CompositeQueryTree) getLocation(d *db.Database) *db.Location { return qt.location } -// QueryTree for CAT queries -type CatQueryTree struct { - subqueries []QueryTree - location *db.Location -} - -// QueryTree for GET queries -type GetQueryTree struct { - bitmap *db.Bitmap - slice int -} - -// QueryTree for SET queries -type SetQueryTree struct { - bitmap *db.Bitmap - profile_id uint64 -} - -// Uses consistent hashing function to select node containing data for GET operation -func (qt *CatQueryTree) getLocation(d *db.Database) *db.Location { - //loc := new(db.Location) - //return loc - if qt.location == nil { - subqueryLength := len(qt.subqueries) - if subqueryLength > 0 { - locationIndex := rand.Intn(subqueryLength) - subquery := qt.subqueries[locationIndex] - qt.location = subquery.getLocation(d) - } - } - return qt.location -} - -// Uses consistent hashing function to select node containing data for GET operation -func (qt *GetQueryTree) getLocation(d *db.Database) *db.Location { - slice := d.GetOrCreateSlice(qt.slice) // TODO: this should probably be just GetSlice (no create) - fragment, err := d.GetFragmentForBitmap(slice, qt.bitmap) - if err != nil { - panic(err) - } - return fragment.GetLocation() -} - -// Uses consistent hashing function to select node containing data for GET operation -func (qt *CountQueryTree) getLocation(d *db.Database) *db.Location { - return qt.subquery.getLocation(d) -} - -// Uses consistent hashing function to select node containing data for GET operation -func (qt *SetQueryTree) getLocation(d *db.Database) *db.Location { - slice, err := d.GetSliceForProfile(qt.profile_id) - fragment, err := d.GetFragmentForBitmap(slice, qt.bitmap) - if err != nil { - panic(err) - } - return fragment.GetLocation() -} - // Builds QueryTree object from Query. Pass slice=-1 to perform operation on all slices func (qp *QueryPlanner) buildTree(query *Query, slice int) QueryTree { var tree QueryTree