// Scan retrieves the values specified in families from the given range. func (c *Client) Scan(s *hrpc.Scan) ([]*pb.Result, error) { var results []*pb.Result var scanres *pb.ScanResponse var rpc *hrpc.Scan ctx := s.GetContext() table := s.Table() families := s.GetFamilies() filters := s.GetFilter() startRow := s.GetStartRow() stopRow := s.GetStopRow() for { // Make a new Scan RPC for this region if rpc == nil { // If it's the first region, just begin at the given startRow rpc, _ = hrpc.NewScanRange(ctx, table, startRow, stopRow, hrpc.Families(families), hrpc.Filters(filters)) } else { // If it's not the first region, we want to start at whatever the // last region's StopKey was rpc, _ = hrpc.NewScanRange(ctx, table, rpc.GetRegionStop(), stopRow, hrpc.Families(families), hrpc.Filters(filters)) } res, err := c.sendRPC(rpc) if err != nil { return nil, err } scanres = res.(*pb.ScanResponse) results = append(results, scanres.Results...) // TODO: The more_results field of the ScanResponse object was always // true, so we should figure out if there's a better way to know when // to move on to the next region than making an extra request and // seeing if there were no results for len(scanres.Results) != 0 { rpc = hrpc.NewScanFromID(ctx, table, *scanres.ScannerId, rpc.Key()) res, err = c.sendRPC(rpc) if err != nil { return nil, err } scanres = res.(*pb.ScanResponse) results = append(results, scanres.Results...) } rpc = hrpc.NewCloseFromID(ctx, table, *scanres.ScannerId, rpc.Key()) if err != nil { return nil, err } res, err = c.sendRPC(rpc) // Check to see if this region is the last we should scan (either // because (1) it's the last region or (3) because its stop_key is // greater than or equal to the stop_key of this scanner provided // that (2) we're not trying to scan until the end of the table). // (1) (2) (3) if len(rpc.GetRegionStop()) == 0 || (len(stopRow) != 0 && bytes.Compare(stopRow, rpc.GetRegionStop()) <= 0) { return results, nil } } }
// Scan retrieves the values specified in families from the given range. func (c *client) Scan(s *hrpc.Scan) ([]*hrpc.Result, error) { var results []*pb.Result var scanres *pb.ScanResponse var rpc *hrpc.Scan ctx := s.Context() table := s.Table() families := s.Families() filters := s.Filter() startRow := s.StartRow() stopRow := s.StopRow() fromTs, toTs := s.TimeRange() maxVerions := s.MaxVersions() numberOfRows := s.NumberOfRows() for { // Make a new Scan RPC for this region if rpc != nil { // If it's not the first region, we want to start at whatever the // last region's StopKey was startRow = rpc.RegionStop() } // TODO: would be nicer to clone it in some way rpc, err := hrpc.NewScanRange(ctx, table, startRow, stopRow, hrpc.Families(families), hrpc.Filters(filters), hrpc.TimeRangeUint64(fromTs, toTs), hrpc.MaxVersions(maxVerions), hrpc.NumberOfRows(numberOfRows)) if err != nil { return nil, err } res, err := c.sendRPC(rpc) if err != nil { return nil, err } scanres = res.(*pb.ScanResponse) results = append(results, scanres.Results...) // TODO: The more_results field of the ScanResponse object was always // true, so we should figure out if there's a better way to know when // to move on to the next region than making an extra request and // seeing if there were no results for len(scanres.Results) != 0 { rpc = hrpc.NewScanFromID(ctx, table, *scanres.ScannerId, rpc.Key()) res, err = c.sendRPC(rpc) if err != nil { return nil, err } scanres = res.(*pb.ScanResponse) results = append(results, scanres.Results...) } rpc = hrpc.NewCloseFromID(ctx, table, *scanres.ScannerId, rpc.Key()) if err != nil { return nil, err } res, err = c.sendRPC(rpc) // Check to see if this region is the last we should scan (either // because (1) it's the last region or (3) because its stop_key is // greater than or equal to the stop_key of this scanner provided // that (2) we're not trying to scan until the end of the table). // (1) if len(rpc.RegionStop()) == 0 || // (2) (3) len(stopRow) != 0 && bytes.Compare(stopRow, rpc.RegionStop()) <= 0 { // Do we want to be returning a slice of Result objects or should we just // put all the Cells into the same Result object? localResults := make([]*hrpc.Result, len(results)) for idx, result := range results { localResults[idx] = hrpc.ToLocalResult(result) } return localResults, nil } } }