static char* test_linear_values()
{
    load_histograms();
    struct hdr_linear_iter iter;
    int index;

    // Raw Histogram
    hdr_linear_iter_init(&iter, raw_histogram, 100000);
    index = 0;
    while (hdr_linear_iter_next(&iter))
    {
        int64_t count_added_in_this_bucket = iter.count_added_in_this_iteration_step;

        if (index == 0)
        {
            mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000);
        }
        else if (index == 999)
        {
            mu_assert("Count at 999 is not 1", count_added_in_this_bucket == 1);
        }
        else
        {
            mu_assert("Count should be 0", count_added_in_this_bucket == 0);
        }

        index++;
    }
    mu_assert("Should of met 1000 values", index == 1000);

    // Corrected Histogram

    hdr_linear_iter_init(&iter, cor_histogram, 10000);
    index = 0;
    int64_t total_added_count = 0;
    while (hdr_linear_iter_next(&iter))
    {
        int64_t count_added_in_this_bucket = iter.count_added_in_this_iteration_step;

        if (index == 0)
        {
            mu_assert("Count at 0 is not 10001", count_added_in_this_bucket == 10001);
        }

        total_added_count += count_added_in_this_bucket;
        index++;
    }
    mu_assert("Should of met 10001 values", index == 10000);
    mu_assert("Should of met 20000 counts", total_added_count == 20000);

    return 0;
}
ERL_NIF_TERM _hi_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    hi_ctx_t* ctx = NULL;
    hh_ctx_t* hdr = NULL;
    hi_opts_t* opts = NULL;

    ErlNifResourceType* hh_ctx_type = get_hh_ctx_type(env);
    ErlNifResourceType* hi_ctx_type = get_hi_ctx_type(env);
    if (argc != 3 ||
        hh_ctx_type == NULL ||
        hi_ctx_type == NULL ||
        !enif_get_resource(env, argv[0], hi_ctx_type, (void **)&ctx) ||
        !enif_get_resource(env, argv[1], hh_ctx_type, (void **)&hdr) ||
        !enif_is_list(env, argv[2]))
    {
        return enif_make_badarg(env);
    }

    opts = (hi_opts_t *)enif_alloc(sizeof(hi_opts_t));
    parse_opts(env, argv[2], opts, (void *)parse_opt);
    uint32_t iterator_type = ctx->type;

    void* it = NULL;

    if (iterator_type == HDR_ITER_REC)
    {
        struct hdr_recorded_iter * iter =
            enif_alloc(sizeof(struct hdr_recorded_iter));
        hdr_recorded_iter_init(iter, hdr->data);
        it = iter;
    }

    if (iterator_type == HDR_ITER_LIN)
    {
        if (opts->linear_value_units_per_bucket <= 0)
        {
            return make_error(env, "bad_linear_value_unit");
        }
        struct hdr_linear_iter * iter =
            enif_alloc(sizeof(struct hdr_linear_iter));
        hdr_linear_iter_init(
            iter,
            hdr->data,
            opts->linear_value_units_per_bucket);
        it = iter;
    }

    if (iterator_type == HDR_ITER_LOG)
    {
        if (opts->log_value_units_first_bucket <= 0)
        {
            return make_error(env, "bad_log_value_unit");
        }
        if (opts->log_base <= 0)
        {
            return make_error(env, "bad_log_base");
        }
        struct hdr_log_iter * iter =
            enif_alloc(sizeof(struct hdr_log_iter));
        hdr_log_iter_init(
            iter,
            hdr->data,
            opts->log_value_units_first_bucket,
            opts->log_base);
        it = iter;
    }

    if (iterator_type == HDR_ITER_PCT)
    {
        if (opts->percentile_ticks_per_half_distance <= 0)
        {
            return make_error(env, "bad_percentile_half_ticks");
        }
        struct hdr_percentile_iter * iter =
            enif_alloc(sizeof(struct hdr_percentile_iter));
        hdr_percentile_iter_init(
            iter,
            hdr->data,
            opts->percentile_ticks_per_half_distance);
        it = iter;
    }

    ctx->type = iterator_type;
    ctx->opts = opts;
    ctx->iter = it;

    return ATOM_OK;
}