'Lookup the *item* with the given hash values in the entries.
Return a (found, entry index) tuple:
- If found is true, <entry index> points to the entry containing
the item.
- If found is false, <entry index> points to the empty entry that
the item can be written to (only if *for_insert* is true)'

def _lookup(self, item, h, for_insert=False):

    context = self._context
    builder = self._builder
    intp_t = h.type
    mask = self.mask
    dtype = self._ty.dtype
    eqfn = context.get_function('==', typing.signature(types.boolean, dtype, dtype))
    one = ir.Constant(intp_t, 1)
    five = ir.Constant(intp_t, 5)
    perturb = cgutils.alloca_once_value(builder, h)
    index = cgutils.alloca_once_value(builder, builder.and_(h, mask))
    if for_insert:
        free_index_sentinel = mask.type((-1))
        free_index = cgutils.alloca_once_value(builder, free_index_sentinel)
    bb_body = builder.append_basic_block('lookup.body')
    bb_found = builder.append_basic_block('lookup.found')
    bb_not_found = builder.append_basic_block('lookup.not_found')
    bb_end = builder.append_basic_block('lookup.end')
    def check_entry(i):
        '\n                                                Check    entry    *i*    against    the    value    being    searched    for.\n                                                '
        entry = self.get_entry(i)
        entry_hash = entry.hash
        with builder.if_then(builder.icmp_unsigned('==', h, entry_hash)):
            eq = eqfn(builder, (item, entry.key))
            with builder.if_then(eq):
                builder.branch(bb_found)
        with builder.if_then(is_hash_empty(context, builder, entry_hash)):
            builder.branch(bb_not_found)
        if for_insert:
            with builder.if_then(is_hash_deleted(context, builder, entry_hash)):
                j = builder.load(free_index)
                j = builder.select(builder.icmp_unsigned('==', j, free_index_sentinel), i, j)
                builder.store(j, free_index)
    with cgutils.for_range(builder, ir.Constant(intp_t, LINEAR_PROBES)):
        i = builder.load(index)
        check_entry(i)
        i = builder.add(i, one)
        i = builder.and_(i, mask)
        builder.store(i, index)
    builder.branch(bb_body)
    with builder.goto_block(bb_body):
        i = builder.load(index)
        check_entry(i)
        p = builder.load(perturb)
        p = builder.lshr(p, five)
        i = builder.add(one, builder.mul(i, five))
        i = builder.and_(mask, builder.add(i, p))
        builder.store(i, index)
        builder.store(p, perturb)
        builder.branch(bb_body)
    with builder.goto_block(bb_not_found):
        if for_insert:
            i = builder.load(index)
            j = builder.load(free_index)
            i = builder.select(builder.icmp_unsigned('==', j, free_index_sentinel), i, j)
            builder.store(i, index)
        builder.branch(bb_end)
    with builder.goto_block(bb_found):
        builder.branch(bb_end)
    builder.position_at_end(bb_end)
    found = builder.phi(ir.IntType(1), 'found')
    found.add_incoming(cgutils.true_bit, bb_found)
    found.add_incoming(cgutils.false_bit, bb_not_found)
    return (found, builder.load(index))
