#include "index.h"
#include "../common/debug.h"
static int64_t fi_next(struct frame_index *fi)
{
return (int64_t)fi->fill*fi->step;
}
static void fi_shrink(struct frame_index *fi)
{
if(fi->fill < 2) return;
else
{
size_t c;
debug2("shrink index with fill %lu and step %lu", (unsigned long)fi->fill, (unsigned long)fi->step);
fi->step *= 2;
fi->fill /= 2;
for(c = 0; c < fi->fill; ++c)
fi->data[c] = fi->data[2*c];
}
fi->next = fi_next(fi);
}
void INT123_fi_init(struct frame_index *fi)
{
fi->data = NULL;
fi->step = 1;
fi->fill = 0;
fi->size = 0;
fi->grow_size = 0;
fi->next = fi_next(fi);
}
void INT123_fi_exit(struct frame_index *fi)
{
debug2("INT123_fi_exit: %p and %lu", (void*)fi->data, (unsigned long)fi->size);
if(fi->size && fi->data != NULL) free(fi->data);
INT123_fi_init(fi);
}
int INT123_fi_resize(struct frame_index *fi, size_t newsize)
{
int64_t *newdata = NULL;
if(newsize == fi->size) return 0;
if(newsize > 0 && newsize < fi->size)
{
while(fi->fill > newsize){ fi_shrink(fi); }
}
newdata = INT123_safe_realloc(fi->data, newsize*sizeof(int64_t));
if(newsize == 0 || newdata != NULL)
{
fi->data = newdata;
fi->size = newsize;
if(fi->fill > fi->size) fi->fill = fi->size;
fi->next = fi_next(fi);
debug2("new index of size %lu at %p", (unsigned long)fi->size, (void*)fi->data);
return 0;
} else
return -1;
}
void INT123_fi_add(struct frame_index *fi, int64_t pos)
{
debug3("wanting to add to fill %lu, step %lu, size %lu", (unsigned long)fi->fill, (unsigned long)fi->step, (unsigned long)fi->size);
if(fi->fill == fi->size)
{
int64_t framenum = fi->fill*fi->step;
if( !(fi->grow_size && INT123_fi_resize(fi, fi->size+fi->grow_size)==0) )
fi_shrink(fi);
if(fi->next != framenum) return;
}
if(fi->fill < fi->size)
{
debug1("adding to index at %p", (void*)(fi->data+fi->fill));
fi->data[fi->fill] = pos;
++fi->fill;
fi->next = fi_next(fi);
debug3("added pos %li to index with fill %lu and step %lu", (long) pos, (unsigned long)fi->fill, (unsigned long)fi->step);
}
}
int INT123_fi_set(struct frame_index *fi, int64_t *offsets, int64_t step, size_t fill)
{
if(INT123_fi_resize(fi, fill) == -1) return -1;
fi->step = step;
if(offsets != NULL)
{
memcpy(fi->data, offsets, fill*sizeof(int64_t));
fi->fill = fill;
}
else
{
fi->fill = 0;
}
fi->next = fi_next(fi);
debug3("set new index of fill %lu, size %lu at %p",
(unsigned long)fi->fill, (unsigned long)fi->size, (void*)fi->data);
return 0;
}
void INT123_fi_reset(struct frame_index *fi)
{
debug1("reset with size %zu", fi->size);
fi->fill = 0;
fi->step = 1;
fi->next = fi_next(fi);
}