line find_slope_intercept(line l) { l.m = find_slope(l.p1,l.p2); if(l.m == INF) l.c = INF; else l.c = l.p1.y - (l.m)*(l.p1.x); return l; }
// do_idx_ent() does the hard work to measure the skews for a single // index entry. We need to determine e->off, the angular offset of // the first lbn of this instance taking the first lbn of parent as // the 0 point and e->alen, the angular offset of the i+1st instance // of e from the ith. void do_idx_ent(struct dm_disk_if *d, // diskmodel struct dm_layout_g4 *l, // root of g4 layout struct idx_ent *e, // the entry in question struct idx *parent, // The index containing e struct idx_ent *parent_e, // The entry for parent in its parent int parent_off, // Which entry we are in parent struct dsstuff *ds, // Disksim instance struct trace *t, // io trace int lbn) { // The first lbn of parent int i; int l0; int dist; double yi; double *times; double *tracetimes; // for bootstrapping off and len double off0time, len0time; int off0lbn[2], len0lbn[2]; // Work internally in floating-point, then convert back to the // integer representation at the end. double aoff = dm_angle_itod(e->off); double alen = dm_angle_itod(e->alen); double period = dm_time_itod(d->mech->dm_period(d)); // Number of instances of this entry. int quot = e->runlen / e->len; // times[i] is disksim's prediction of the amount of time to access the // first lbn of the ith instance after accessing the first instance. times = calloc(quot, sizeof(double)); // Actual times from the trace replay against the real disk. tracetimes = calloc(quot, sizeof(double)); // li[i] contains the first lbn of the ith instance of e. int *li = calloc(quot, sizeof(*li)); printf("%s() lbn %d e->lbn %d alen %f off %f quot %d\n", __func__, lbn, e->lbn, alen, aoff, quot); if(e->alen != 0 || e->off != 0) { printf("%s() already done, apparently\n", __func__); return; } // Bootstrap offset by measuring the first instance. if(e->lbn != 0) { aoff = measure_one_skew(d, ds, t, lbn, lbn + e->lbn); e->off = dm_angle_dtoi(aoff); } // Check for the end of the lbn space. if(lbn + e->lbn + e->len >= d->dm_sectors) { e->alen = dm_angle_dtoi(0.0); return; } // Bootstrap alen by measuring the skew from the first to the second // instance. alen = measure_one_skew(d, ds, t, lbn + e->lbn, lbn + e->lbn + e->len); e->alen = dm_angle_dtoi(alen); printf("first off %f len %f\n", aoff, alen); // Expand out the lbns of all of the instances. For calibration // (second pass), read in the values from the trace. To generate // the trace (first pass), time how long it takes to read the first // lbn of the ith instance after reading the last lbn on the first // track of the first instance. for(i = 1; i < quot; i++) { l0 = lbn; li[i] = l0 + e->lbn + e->len * i; adjust_lbns(d, &l0, &li[i]); if(mode == CALIB) { tracetimes[i] = get_tracetime(t, l0, li[i]); printf("%d (%d,%d) trace %f pred %f\n", i, l0, li[i], tracetimes[i], times[i]); } else { time_second_request(l0, li[i], ds, t, d); } } if(mode == GENTRACE) { return; } // Now calibrate the value. We first look at the first 2 instances, // then 4, then 8, etc, refining our estimate at each step. for(dist = 2; dist < quot ; ) { // y = a + bx; r is the correlation coeffecient. double a, b; for(i = 1; i < dist; i++) { times[i] = time_second_request(l0, li[i], ds, t, d); printf("%d (%d,%d) trace %f pred %f\n", i, l0, li[i], tracetimes[i], times[i]); } // Do a linear least squares fit of the difference between the // predicted and actual service times. The slope (b) of that line // corresponds to the error in our estimate of alen and the y // intercept corresponds to the error in our estimate of off. b = find_slope(times, tracetimes, dist, &a, period); // Adjust the instance-to-instance skew according to the fit. alen = fix_angle(alen - b / period); e->alen = dm_angle_dtoi(alen); // If e is the first instance in its parent index, its offset is // defined to be 0. Otherwise, correct according to the fit. if(e->lbn > lbn) { printf("fix aoff (%d, %d)\n", lbn, e->lbn); aoff = fix_angle(aoff - a / period); e->off = dm_angle_dtoi(aoff); } printf("alen -> %f, off -> %f (dist %d)\n", alen, aoff, dist); if(dist == quot) { break; } else if(dist * 2 >= quot) { dist = quot; } else { dist *= 2; } } free(li); free(tracetimes); free(times); return; }
//Insert your line algorithm here void draw_line(int x0, int y0, int x1, int y1, screen s, color c) { if (x0 > x1){ draw_line(x1, y1, x0, y0, s, c); } else { int slope, x, y, A, B, d; x = x0; y = y0; A = y1 - y0; B = -(x1 - x0); slope = find_slope(x0, y0, x1, y1); if (slope == 1){ //printf("First\n"); d = 2 * A + B; while (x <= x1){ plot(s, c, x, y); if (d > 0){ y += 1; d += 2 * B; } x += 1; d += 2 * A; } } if (slope == 2){ //printf("Second\n"); d = A + 2 * B; while (y <= y1){ plot(s, c, x, y); if (d < 0){ x += 1; d += 2 * A; } y += 1; d += 2 * B; } } if (slope == 3){ //printf("Seventh\n"); d = A - 2 * B; while (y >= y1){ plot(s, c, x, y); if (d < 0){ x += 1; d -= 2 * A; } y -= 1; d += 2 * B; } } if (slope == 4){ //printf("Eigth\n"); d = 2 * A - B; while (x <= x1){ plot(s, c, x, y); if (d > 0){ y -= 1; d += 2 * B; } x += 1; d -= 2 * A; } } } }