code: def _numba_equi_ge_join(
      left_index,
      right_index,
      slice_starts,
      slice_ends,
      ge_arr1,
      ge_arr2,
      ge_strict,
  ):
      """
      Get indices for an equi join
      and a greater than join
      """
  
      length = left_index.size
      ends = np.empty(length, dtype=np.intp)
      booleans = np.ones(length, dtype=np.bool_)
      # sizes array is used to track the exact
      # number of matches per slice_start
      sizes = np.empty(length, dtype=np.intp)
      counts = 0
      for num in prange(length):
          l1 = ge_arr1[num]
          slice_start = slice_starts[num]
          slice_end = slice_ends[num]
          r1 = ge_arr2[slice_start:slice_end]
          end = np.searchsorted(r1, l1, side="right")
          if end > 0:
              if ge_strict and (l1 == r1[end - 1]):
                  end = np.searchsorted(r1, l1, side="left")
          if end == 0:
              counts += 1
              booleans[num] = False
          else:
              ends[num] = slice_start + end
              sizes[num] = end
      if counts == length:
          return None, None
      if counts > 0:
          left_index = left_index[booleans]
          ends = ends[booleans]
          slice_starts = slice_starts[booleans]
          sizes = sizes[booleans]
      slice_ends = ends
      ends = None
      # build the left and right indices
      # idea is to populate the indices
      # based on the number of matches
      # per slice_start and ensure alignment with the
      # slice_start during the iteration
      cum_sizes = np.cumsum(sizes)
      starts = np.empty(slice_ends.size, dtype=np.intp)
      starts[0] = 0
      starts[1:] = cum_sizes[:-1]
      r_index = np.empty(cum_sizes[-1], dtype=np.intp)
      l_index = np.empty(cum_sizes[-1], dtype=np.intp)
      for num in prange(slice_ends.size):
          start = starts[num]
          r_ind = slice_starts[num]
          l_ind = left_index[num]
          width = sizes[num]
          if width == 1:
              r_index[start] = right_index[r_ind]
              l_index[start] = l_ind
          else:
              for n in range(width):
                  indexer = start + n
                  r_index[indexer] = right_index[r_ind + n]
                  l_index[indexer] = l_ind
  
      return l_index, r_index
  
file_path: pyjanitor/janitor/functions/_numba.py
imports: import numpy
  import pandas
  from numba import njit, prange
  from pandas.api.types import is_datetime64_dtype, is_extension_array_dtype
  from janitor.functions.utils import _generic_func_cond_join, _null_checks_cond_join, greater_than_join_types, less_than_join_types
label_desc: Use image node_id 4 for calling a global function with example usage: _numba_equi_ge_join(left_index, right_index, slice_starts, slice_ends, ge_arr1, ge_arr2, ge_strict) and returns: l_index,  r_index, None,  None