Untitled

mail@pastecode.io avatar
unknown
c_cpp
8 months ago
3.2 kB
2
Indexable
Never
#ifndef _WINDOW_BIT_COUNT_APX_
#define _WINDOW_BIT_COUNT_APX_

#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

uint64_t N_MERGES = 0;  // keep track of how many bucket merges occur

/*
    TODO: You can add code here.
*/
typedef struct {
    uint32_t size;  // bucket size
    uint32_t ts;    // the timestamp
} Bucket;

typedef struct {
    // TODO: Fill me.
    uint32_t wnd_size;        // input
    uint32_t k;               // input
    uint32_t now;             // current ts
    uint32_t idx_oldest;      // index of the oldest bucket
    uint32_t idx_newest;      // index of the newest bucket
    uint32_t max_bucket_cnt;  // max count of the buckets (max_groups * max_buckets_in_group)
    Bucket* buckets;          // the bucket buffer
    uint32_t bit_cnt;         // the apx answer we are calculating
} StateApx;

// k = 1/eps
// if eps = 0.01 (relative error 1%) then k = 100
// if eps = 0.001 (relative error 0.1%) the k = 1000
uint64_t wnd_bit_count_apx_new(StateApx* self, uint32_t wnd_size, uint32_t k) {
    assert(wnd_size >= 1);
    assert(k >= 1);

    // TODO: Fill me.
    self->wnd_size = wnd_size;
    self->k = k;
    self->now = 0;
    self->idx_oldest = 0;
    self->idx_newest = 0;

    uint32_t max_groups = 1 + log2((wnd_size - 1) / k + 1);
    uint32_t max_buckets_in_group = k + 1;
    self->max_bucket_cnt = max_groups * max_buckets_in_group;

    uint64_t memory = ((uint64_t)self->max_bucket_cnt) * sizeof(Bucket);
    self->buckets = (Bucket*)malloc(memory);
    for (uint32_t i = 0; i < self->max_bucket_cnt; i++) {
        self->buckets[i].ts = -1;
        self->buckets[i].size = -1;
    }

    self->bit_cnt = 0;

    // TODO:
    // The function should return the total number of bytes allocated on the heap.
    return memory;
}

void wnd_bit_count_apx_destruct(StateApx* self) {
    // TODO: Fill me.
    // Make sure you free the memory allocated on the heap.
    free(self->buckets);
}

void wnd_bit_count_apx_print(StateApx* self) {
    // This is useful for debugging.
}

uint32_t wnd_bit_count_apx_next(StateApx* self, bool item) {
    // TODO: Fill me.
    self->now += 1;

    // If the oldest bucket falls out the window, remove it
    if (self->now - self->buckets[self->idx_oldest].ts >= self->wnd_size && self->buckets[self->idx_oldest].ts != -1) {
        self->idx_oldest = (self->idx_oldest + 1) % self->max_bucket_cnt;
        self->bit_cnt -= self->buckets[self->idx_oldest].size;
    }

    if (item == 1) {
        self->idx_newest = (self->idx_newest + 1) % self->max_bucket_cnt;
        self->bit_cnt += 1;

        // Add new bucket to the bucket buffer
        self->buckets[self->idx_newest].size = 1;
        self->buckets[self->idx_newest].ts = self->now;

        // Traverse bucket buffer from newest to oldest
        // If a group has (k + 2) buckets, merge the oldest two
        if (self->idx_newest > self->idx_oldest) { // Normal case

        } else { // The idx_newest is wrapped around

        }
    }

    return self->bit_cnt;
}

#endif  // _WINDOW_BIT_COUNT_APX_
Leave a Comment