stepcompress: Be consistent with "point" vs "nextpoint"

Make it clear which variables refer to the best verified point found
so far, and which variables deal with the next (not yet verified)
point.

Also, remove checked_count as bestcount serves the same purpose.

Also, allow minmax_point to be inlined.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2016-12-13 10:44:26 -05:00
parent 1dbd11446c
commit a217c0f394
1 changed files with 35 additions and 33 deletions

View File

@ -17,6 +17,7 @@
#include <math.h> // sqrt #include <math.h> // sqrt
#include <stddef.h> // offsetof #include <stddef.h> // offsetof
#include <stdint.h> // uint32_t #include <stdint.h> // uint32_t
#include <stdio.h> // fprintf
#include <stdlib.h> // malloc #include <stdlib.h> // malloc
#include <string.h> // memset #include <string.h> // memset
#include "pyhelper.h" // errorf #include "pyhelper.h" // errorf
@ -100,7 +101,7 @@ struct points {
// Given a requested step time, return the minimum and maximum // Given a requested step time, return the minimum and maximum
// acceptable times // acceptable times
static struct points static inline struct points
minmax_point(struct stepcompress *sc, uint64_t *pos) minmax_point(struct stepcompress *sc, uint64_t *pos)
{ {
uint32_t prevpoint = pos > sc->queue_pos ? *(pos-1) - sc->last_step_clock : 0; uint32_t prevpoint = pos > sc->queue_pos ? *(pos-1) - sc->last_step_clock : 0;
@ -131,52 +132,53 @@ compress_bisect_add(struct stepcompress *sc)
int32_t outer_mininterval = point.minp, outer_maxinterval = point.maxp; int32_t outer_mininterval = point.minp, outer_maxinterval = point.maxp;
int32_t add = 0, minadd = -0x8001, maxadd = 0x8000; int32_t add = 0, minadd = -0x8001, maxadd = 0x8000;
int32_t bestinterval = 0, bestcount = 1, bestadd = 1, bestreach = INT32_MIN; int32_t bestinterval = 0, bestcount = 1, bestadd = 1, bestreach = INT32_MIN;
int32_t checked_count = 0;
for (;;) { for (;;) {
// Find longest valid sequence with the given 'add' // Find longest valid sequence with the given 'add'
int32_t mininterval = outer_mininterval, maxinterval = outer_maxinterval; struct points nextpoint;
int32_t count = 1, addfactor = 0; int32_t nextmininterval = outer_mininterval;
int32_t nextmaxinterval = outer_maxinterval, interval = nextmaxinterval;
int32_t nextcount = 1;
for (;;) { for (;;) {
if (count > checked_count) { nextcount++;
if (&sc->queue_pos[count] >= sc->queue_next || count >= 65535 if (nextcount > bestcount
|| sc->queue_pos[count] >= sc->last_step_clock + (3<<28)) && (&sc->queue_pos[nextcount-1] >= sc->queue_next
return (struct step_move){ maxinterval, count, add }; || sc->queue_pos[nextcount-1] >= sc->last_step_clock+(3<<28)
checked_count++; || nextcount > 65535)) {
int32_t count = nextcount - 1;
return (struct step_move){ interval, count, add };
} }
point = minmax_point(sc, sc->queue_pos + count); nextpoint = minmax_point(sc, sc->queue_pos + nextcount - 1);
addfactor += count; int32_t nextaddfactor = nextcount*(nextcount-1)/2;
int32_t c = add*addfactor; int32_t c = add*nextaddfactor;
int32_t nextmininterval = mininterval; if (nextmininterval*nextcount < nextpoint.minp - c)
if (c + nextmininterval*(count+1) < point.minp) nextmininterval = DIV_UP(nextpoint.minp - c, nextcount);
nextmininterval = DIV_UP(point.minp - c, count+1); if (nextmaxinterval*nextcount > nextpoint.maxp - c)
int32_t nextmaxinterval = maxinterval; nextmaxinterval = (nextpoint.maxp - c) / nextcount;
if (c + nextmaxinterval*(count+1) > point.maxp)
nextmaxinterval = (point.maxp - c) / (count+1);
if (nextmininterval > nextmaxinterval) if (nextmininterval > nextmaxinterval)
break; break;
count += 1; interval = nextmaxinterval;
mininterval = nextmininterval;
maxinterval = nextmaxinterval;
} }
// Check if this is the best sequence found so far // Check if this is the best sequence found so far
int32_t reach = add*(addfactor-count) + maxinterval*count; int32_t count = nextcount - 1, addfactor = count*(count-1)/2;
int32_t reach = add*addfactor + interval*count;
if (reach > bestreach && (bestadd || count > bestcount + bestcount/16)) { if (reach > bestreach && (bestadd || count > bestcount + bestcount/16)) {
bestinterval = maxinterval; bestinterval = interval;
bestcount = count; bestcount = count;
bestadd = add; bestadd = add;
bestreach = reach; bestreach = reach;
} }
// Check if a greater or lesser add could extend the sequence // Check if a greater or lesser add could extend the sequence
int32_t nextreach = add*addfactor + maxinterval*(count+1); int32_t nextaddfactor = nextcount*(nextcount-1)/2;
if (nextreach < point.minp) { int32_t nextreach = add*nextaddfactor + interval*nextcount;
if (nextreach < nextpoint.minp) {
minadd = add; minadd = add;
outer_maxinterval = maxinterval; outer_maxinterval = nextmaxinterval;
} else { } else {
maxadd = add; maxadd = add;
outer_mininterval = mininterval; outer_mininterval = nextmininterval;
} }
// The maximum valid deviation between two quadratic sequences // The maximum valid deviation between two quadratic sequences
@ -190,12 +192,12 @@ compress_bisect_add(struct stepcompress *sc)
} }
// See if next point would further limit the add range // See if next point would further limit the add range
if ((minadd+1)*addfactor + outer_maxinterval*(count+1) < point.minp) int32_t c = outer_maxinterval * nextcount;
minadd = idiv_up(point.minp - outer_maxinterval*(count+1) if ((minadd+1)*nextaddfactor < nextpoint.minp - c)
, addfactor) - 1; minadd = idiv_up(nextpoint.minp - c, nextaddfactor) - 1;
if ((maxadd-1)*addfactor + outer_mininterval*(count+1) > point.maxp) c = outer_mininterval * nextcount;
maxadd = idiv_down(point.maxp - outer_mininterval*(count+1) if ((maxadd-1)*nextaddfactor > nextpoint.maxp - c)
, addfactor) + 1; maxadd = idiv_down(nextpoint.maxp - c, nextaddfactor) + 1;
// Bisect valid add range and try again with new 'add' // Bisect valid add range and try again with new 'add'
add = (minadd + maxadd) / 2; add = (minadd + maxadd) / 2;