'Binary search implementation used in all get functions'

def _find_key_in_leaf_using_binary_search(self, key, leaf_start, nr_of_elements, doc_id=None, mode=None, return_closest=False):

    (imin, imax) = (0, (nr_of_elements - 1))
    (buffer_start, buffer_end) = self._set_buffer_limits()
    (candidate_start, candidate_index, move_buffer) = self._choose_next_candidate_index_in_leaf(leaf_start, self._calculate_key_position(leaf_start, ((imin + imax) / 2), 'l'), buffer_start, buffer_end, imin, imax)
    while ((imax != imin) and (imax > imin)):
        (curr_key, curr_doc_id, curr_start, curr_size, curr_status) = self._read_single_leaf_record(leaf_start, candidate_index)
        candidate_start = self._calculate_key_position(leaf_start, candidate_index, 'l')
        if (key < curr_key):
            if (move_buffer == MOVE_BUFFER_PREV):
                (buffer_start, buffer_end) = self._prev_buffer(buffer_start, buffer_end)
            else:
                (move_buffer is None)
            imax = (candidate_index - 1)
            (candidate_start, candidate_index, move_buffer) = self._choose_next_candidate_index_in_leaf(leaf_start, candidate_start, buffer_start, buffer_end, imin, imax)
        elif (key == curr_key):
            if (mode == MODE_LAST):
                if (move_buffer == MOVE_BUFFER_NEXT):
                    (buffer_start, buffer_end) = self._next_buffer(buffer_start, buffer_end)
                else:
                    (move_buffer is None)
                imin = (candidate_index + 1)
                (candidate_start, candidate_index, move_buffer) = self._choose_next_candidate_index_in_leaf(leaf_start, candidate_start, buffer_start, buffer_end, imin, imax)
            elif (curr_status == 'o'):
                break
            else:
                if (move_buffer == MOVE_BUFFER_PREV):
                    (buffer_start, buffer_end) = self._prev_buffer(buffer_start, buffer_end)
                else:
                    (move_buffer is None)
                imax = candidate_index
                (candidate_start, candidate_index, move_buffer) = self._choose_next_candidate_index_in_leaf(leaf_start, candidate_start, buffer_start, buffer_end, imin, imax)
        else:
            if (move_buffer == MOVE_BUFFER_NEXT):
                (buffer_start, buffer_end) = self._next_buffer(buffer_start, buffer_end)
            else:
                (move_buffer is None)
            imin = (candidate_index + 1)
            (candidate_start, candidate_index, move_buffer) = self._choose_next_candidate_index_in_leaf(leaf_start, candidate_start, buffer_start, buffer_end, imin, imax)
    if (imax > imin):
        chosen_key_position = candidate_index
    else:
        chosen_key_position = imax
    (curr_key, curr_doc_id, curr_start, curr_size, curr_status) = self._read_single_leaf_record(leaf_start, chosen_key_position)
    if (key != curr_key):
        if return_closest:
            return (leaf_start, chosen_key_position)
        else:
            raise ElemNotFound
    if (doc_id and (doc_id == curr_doc_id) and (curr_status == 'o')):
        return (leaf_start, chosen_key_position, curr_doc_id, curr_key, curr_start, curr_size, curr_status)
    else:
        if ((mode == MODE_FIRST) and (imin < chosen_key_position)):
            matching_record_index = self._leaf_linear_key_search(key, self._calculate_key_position(leaf_start, imin, 'l'), imin, chosen_key_position)
        else:
            matching_record_index = chosen_key_position
        (curr_key, curr_doc_id, curr_start, curr_size, curr_status) = self._read_single_leaf_record(leaf_start, matching_record_index)
        if ((curr_status == 'd') and (not return_closest)):
            (leaf_start, nr_of_elements, matching_record_index) = self._find_existing(key, matching_record_index, leaf_start, nr_of_elements)
            (curr_key, curr_doc_id, curr_start, curr_size, curr_status) = self._read_single_leaf_record(leaf_start, matching_record_index)
        if ((doc_id is not None) and (doc_id != curr_doc_id)):
            (leaf_start, nr_of_elements, matching_record_index) = self._match_doc_id(doc_id, key, matching_record_index, leaf_start, nr_of_elements)
            (curr_key, curr_doc_id, curr_start, curr_size, curr_status) = self._read_single_leaf_record(leaf_start, matching_record_index)
        return (leaf_start, matching_record_index, curr_doc_id, curr_key, curr_start, curr_size, curr_status)
