func (c *client) establishRegion(originalReg hrpc.RegionInfo, host string, port uint16) { var err error reg := originalReg backoff := backoffStart for { ctx, _ := context.WithTimeout(context.Background(), regionLookupTimeout) if port != 0 && err == nil { // If this isn't the admin or meta region, check if a client // for this host/port already exists if c.clientType != adminClient && reg != c.metaRegionInfo { client := c.clients.checkForClient(host, port) if client != nil { // There's already a client, add it to the // region and mark it as available. reg.SetClient(client) c.clients.put(client, reg) originalReg.MarkAvailable() return } } // Make this channel buffered so that if we time out we don't // block the newRegion goroutine forever. ch := make(chan newRegResult, 1) var clientType region.ClientType if c.clientType == standardClient { clientType = region.RegionClient } else { clientType = region.MasterClient } go newRegionClient(ctx, ch, clientType, host, port, c.rpcQueueSize, c.flushInterval) select { case res := <-ch: if res.Err == nil { reg.SetClient(res.Client) if c.clientType != adminClient && reg != c.metaRegionInfo { // put will set region client so that as soon as we add // it to the key->region mapping, concurrent readers are // able to find the client c.clients.put(res.Client, reg) if reg != originalReg { removed := c.regions.put(reg) for _, r := range removed { c.clients.del(r) } } } originalReg.MarkAvailable() return } else { err = res.Err } case <-ctx.Done(): err = ErrDeadline } } if err != nil { if err == TableNotFound { c.regions.del(originalReg.Name()) originalReg.MarkAvailable() return } // This will be hit if either there was an error locating the // region, or the region was located but there was an error // connecting to it. backoff, err = sleepAndIncreaseBackoff(ctx, backoff) if err != nil { continue } } if c.clientType == adminClient { host, port, err = c.zkLookup(ctx, c.master) } else if reg == c.metaRegionInfo { host, port, err = c.zkLookup(ctx, c.meta) } else { reg, host, port, err = c.locateRegion(ctx, originalReg.Table(), originalReg.StartKey()) } } }
func isRegionOverlap(regA, regB hrpc.RegionInfo) bool { return bytes.Equal(regA.Table(), regB.Table()) && bytes.Compare(regA.StartKey(), regB.StopKey()) < 0 && bytes.Compare(regA.StopKey(), regB.StartKey()) > 0 }