#include <sys/types.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <sys/tim_filter.h>
void
reset_time(struct time_filter *tf, uint32_t time_len)
{
tf->cur_time_limit = time_len;
}
void
reset_time_small(struct time_filter_small *tf, uint32_t time_len)
{
tf->cur_time_limit = time_len;
}
int
setup_time_filter(struct time_filter *tf, int fil_type, uint32_t time_len)
{
uint64_t set_val;
int i;
if ((fil_type != FILTER_TYPE_MIN) &&
(fil_type != FILTER_TYPE_MAX))
return(EINVAL);
if (time_len < NUM_FILTER_ENTRIES)
return(EINVAL);
if (fil_type == FILTER_TYPE_MIN)
set_val = 0xffffffffffffffff;
else
set_val = 0;
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = set_val;
tf->entries[i].time_up = 0;
}
tf->cur_time_limit = time_len;
return(0);
}
int
setup_time_filter_small(struct time_filter_small *tf, int fil_type, uint32_t time_len)
{
uint32_t set_val;
int i;
if ((fil_type != FILTER_TYPE_MIN) &&
(fil_type != FILTER_TYPE_MAX))
return(EINVAL);
if (time_len < NUM_FILTER_ENTRIES)
return(EINVAL);
if (fil_type == FILTER_TYPE_MIN)
set_val = 0xffffffff;
else
set_val = 0;
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = set_val;
tf->entries[i].time_up = 0;
}
tf->cur_time_limit = time_len;
return(0);
}
static void
check_update_times(struct time_filter *tf, uint64_t value, uint32_t now)
{
int i, j, fnd;
uint32_t tim;
uint32_t time_limit;
for(i=0; i<(NUM_FILTER_ENTRIES-1); i++) {
tim = now - tf->entries[i].time_up;
time_limit = (tf->cur_time_limit * (NUM_FILTER_ENTRIES-i))/NUM_FILTER_ENTRIES;
if (tim >= time_limit) {
fnd = 0;
for(j=(i+1); j<NUM_FILTER_ENTRIES; j++) {
if (tf->entries[i].time_up < tf->entries[j].time_up) {
tf->entries[i].value = tf->entries[j].value;
tf->entries[i].time_up = tf->entries[j].time_up;
fnd = 1;
break;
}
}
if (fnd == 0) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
}
}
i = NUM_FILTER_ENTRIES-1;
tim = now - tf->entries[i].time_up;
time_limit = (tf->cur_time_limit * (NUM_FILTER_ENTRIES-i))/NUM_FILTER_ENTRIES;
if (tim >= time_limit) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
}
static void
check_update_times_small(struct time_filter_small *tf, uint32_t value, uint32_t now)
{
int i, j, fnd;
uint32_t tim;
uint32_t time_limit;
for(i=0; i<(NUM_FILTER_ENTRIES-1); i++) {
tim = now - tf->entries[i].time_up;
time_limit = (tf->cur_time_limit * (NUM_FILTER_ENTRIES-i))/NUM_FILTER_ENTRIES;
if (tim >= time_limit) {
fnd = 0;
for(j=(i+1); j<NUM_FILTER_ENTRIES; j++) {
if (tf->entries[i].time_up < tf->entries[j].time_up) {
tf->entries[i].value = tf->entries[j].value;
tf->entries[i].time_up = tf->entries[j].time_up;
fnd = 1;
break;
}
}
if (fnd == 0) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
}
}
i = NUM_FILTER_ENTRIES-1;
tim = now - tf->entries[i].time_up;
time_limit = (tf->cur_time_limit * (NUM_FILTER_ENTRIES-i))/NUM_FILTER_ENTRIES;
if (tim >= time_limit) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
}
void
filter_reduce_by(struct time_filter *tf, uint64_t reduce_by, uint32_t now)
{
int i;
if (reduce_by < tf->entries[0].value)
tf->entries[0].value -= reduce_by;
else
tf->entries[0].value = 0;
tf->entries[0].time_up = now;
for(i=1; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = tf->entries[0].value;
tf->entries[i].time_up = now;
}
}
void
filter_reduce_by_small(struct time_filter_small *tf, uint32_t reduce_by, uint32_t now)
{
int i;
if (reduce_by < tf->entries[0].value)
tf->entries[0].value -= reduce_by;
else
tf->entries[0].value = 0;
tf->entries[0].time_up = now;
for(i=1; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = tf->entries[0].value;
tf->entries[i].time_up = now;
}
}
void
filter_increase_by(struct time_filter *tf, uint64_t incr_by, uint32_t now)
{
int i;
tf->entries[0].value += incr_by;
tf->entries[0].time_up = now;
for(i=1; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = tf->entries[0].value;
tf->entries[i].time_up = now;
}
}
void
filter_increase_by_small(struct time_filter_small *tf, uint32_t incr_by, uint32_t now)
{
int i;
tf->entries[0].value += incr_by;
tf->entries[0].time_up = now;
for(i=1; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = tf->entries[0].value;
tf->entries[i].time_up = now;
}
}
void
forward_filter_clock(struct time_filter *tf, uint32_t ticks_forward)
{
int i;
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].time_up += ticks_forward;
}
}
void
forward_filter_clock_small(struct time_filter_small *tf, uint32_t ticks_forward)
{
int i;
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].time_up += ticks_forward;
}
}
void
tick_filter_clock(struct time_filter *tf, uint32_t now)
{
int i;
uint32_t tim, time_limit;
for(i=(NUM_FILTER_ENTRIES-2); i>=0 ; i--) {
tim = now - tf->entries[i].time_up;
time_limit = (tf->cur_time_limit * (NUM_FILTER_ENTRIES-i))/NUM_FILTER_ENTRIES;
if (tim >= time_limit) {
tf->entries[i].value = tf->entries[(i+1)].value;
tf->entries[i].time_up = tf->entries[(i+1)].time_up;
}
}
}
void
tick_filter_clock_small(struct time_filter_small *tf, uint32_t now)
{
int i;
uint32_t tim, time_limit;
for(i=(NUM_FILTER_ENTRIES-2); i>=0 ; i--) {
tim = now - tf->entries[i].time_up;
time_limit = (tf->cur_time_limit * (NUM_FILTER_ENTRIES-i))/NUM_FILTER_ENTRIES;
if (tim >= time_limit) {
tf->entries[i].value = tf->entries[(i+1)].value;
tf->entries[i].time_up = tf->entries[(i+1)].time_up;
}
}
}
uint32_t
apply_filter_min(struct time_filter *tf, uint64_t value, uint32_t now)
{
int i, j;
if (value <= tf->entries[0].value) {
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
return (tf->entries[0].value);
}
for (j=1; j<NUM_FILTER_ENTRIES; j++) {
if (value <= tf->entries[j].value) {
for(i=j; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
break;
}
}
check_update_times(tf, value, now);
return (tf->entries[0].value);
}
uint32_t
apply_filter_min_small(struct time_filter_small *tf,
uint32_t value, uint32_t now)
{
int i, j;
if (value <= tf->entries[0].value) {
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
return (tf->entries[0].value);
}
for (j=1; j<NUM_FILTER_ENTRIES; j++) {
if (value <= tf->entries[j].value) {
for(i=j; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
break;
}
}
check_update_times_small(tf, value, now);
return (tf->entries[0].value);
}
uint32_t
apply_filter_max(struct time_filter *tf, uint64_t value, uint32_t now)
{
int i, j;
if (value >= tf->entries[0].value) {
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
return (tf->entries[0].value);
}
for (j=1; j<NUM_FILTER_ENTRIES; j++) {
if (value >= tf->entries[j].value) {
for(i=j; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
break;
}
}
check_update_times(tf, value, now);
return (tf->entries[0].value);
}
uint32_t
apply_filter_max_small(struct time_filter_small *tf,
uint32_t value, uint32_t now)
{
int i, j;
if (value >= tf->entries[0].value) {
for(i=0; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
return (tf->entries[0].value);
}
for (j=1; j<NUM_FILTER_ENTRIES; j++) {
if (value >= tf->entries[j].value) {
for(i=j; i<NUM_FILTER_ENTRIES; i++) {
tf->entries[i].value = value;
tf->entries[i].time_up = now;
}
break;
}
}
check_update_times_small(tf, value, now);
return (tf->entries[0].value);
}