Author: stefan2
Date: Tue Jun 11 13:11:36 2013
New Revision: 1491784
URL: http://svn.apache.org/r1491784
Log:
On the fsfs-format7 branch: Teach the fsfs-access-map tool to
generate scaled / rectangular heatmaps as well.
* tools/dev/fsfs-access-map.c
(color_t): declare a new data type
(add_sample,
scale_line): new scaling utility functions
(write_bitmap): add scaling option
(main): generate scaled and non-scaled heat maps
Modified:
subversion/branches/fsfs-format7/tools/dev/fsfs-access-map.c
Modified: subversion/branches/fsfs-format7/tools/dev/fsfs-access-map.c
URL:
http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/tools/dev/fsfs-access-map.c?rev=1491784&r1=1491783&r2=1491784&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/tools/dev/fsfs-access-map.c (original)
+++ subversion/branches/fsfs-format7/tools/dev/fsfs-access-map.c Tue Jun 11
13:11:36 2013
@@ -92,6 +92,9 @@ typedef struct handle_info_t
typedef unsigned char byte;
typedef unsigned short word;
+/* an RGB color */
+typedef byte color_t[3];
+
/* global const char * file name -> *file_info_t map */
static apr_hash_t *files = NULL;
@@ -509,17 +512,82 @@ write_bitmap_header(apr_file_t *file, in
apr_file_write(file, header, &written);
}
-/* write the cluster read map for all files in INFO as BMP image to FILE.
+/* To COLOR, add the fractional value of SOURCE from fractional indexes
+ * SOURCE_START to SOURCE_END and apply the SCALING_FACTOR.
+ */
+static void
+add_sample(color_t color,
+ color_t *source,
+ double source_start,
+ double source_end,
+ double scaling_factor)
+{
+ double factor = (source_end - source_start) / scaling_factor;
+
+ apr_size_t i;
+ for (i = 0; i < sizeof(color_t) / sizeof(*color); ++i)
+ color[i] += (source_end - source_start < 0.5) && source_start > 1.0
+ ? factor * source[(apr_size_t)source_start - 1][i]
+ : factor * source[(apr_size_t)source_start][i];
+}
+
+/* Scale the IN_LEN RGB values from IN to OUT_LEN RGB values in OUT.
+ */
+static void
+scale_line(color_t* out,
+ apr_size_t out_len,
+ color_t *in,
+ apr_size_t in_len)
+{
+ double scaling_factor = (double)(in_len) / (double)(out_len);
+
+ apr_size_t i;
+ memset(out, 0, out_len * sizeof(color_t));
+ for (i = 0; i < out_len; ++i)
+ {
+ color_t color = { 0 };
+
+ double source_start = i * scaling_factor;
+ double source_end = (i + 1) * scaling_factor;
+
+ if ((apr_size_t)source_start == (apr_size_t)source_end)
+ {
+ add_sample(color, in, source_start, source_end, scaling_factor);
+ }
+ else
+ {
+ apr_size_t k;
+ apr_size_t first_sample_end = (apr_size_t)source_start + 1;
+ apr_size_t last_sample_start = (apr_size_t)source_end;
+
+ add_sample(color, in, source_start, first_sample_end,
scaling_factor);
+ for (k = first_sample_end; k < last_sample_start; ++k)
+ add_sample(color, in, k, k + 1, scaling_factor);
+
+ add_sample(color, in, last_sample_start, source_end, scaling_factor);
+ }
+
+ memcpy(out[i], color, sizeof(color));
+ }
+}
+
+/* Write the cluster read map for all files in INFO as BMP image to FILE.
+ * If MAX_X is not 0, scale all lines to MAX_X pixels. Use POOL for
+ * allocations.
*/
static void
-write_bitmap(apr_array_header_t *info, apr_file_t *file)
+write_bitmap(apr_array_header_t *info,
+ apr_size_t max_x,
+ apr_file_t *file,
+ apr_pool_t *pool)
{
int ysize = info->nelts;
int xsize = 0;
int x, y;
int row_size;
- int padding;
apr_size_t written;
+ color_t *line, *scaled_line;
+ svn_boolean_t do_scale = max_x > 0;
/* xsize = max cluster number */
for (y = 0; y < ysize; ++y)
@@ -531,37 +599,40 @@ write_bitmap(apr_array_header_t *info, a
xsize = 0x3fff;
if (ysize >= 0x4000)
ysize = 0x3fff;
+ if (max_x == 0)
+ max_x = xsize;
/* rows in BMP files must be aligned to 4 bytes */
- row_size = APR_ALIGN(xsize * 3, 4);
- padding = row_size - xsize * 3;
+ row_size = APR_ALIGN(max_x * sizeof(color_t), 4);
+ /**/
+ line = apr_pcalloc(pool, xsize * sizeof(color_t));
+ scaled_line = apr_pcalloc(pool, row_size);
+
/* write header to file */
- write_bitmap_header(file, xsize, ysize);
+ write_bitmap_header(file, max_x, ysize);
/* write all rows */
for (y = 0; y < ysize; ++y)
{
file_stats_t *file_info = APR_ARRAY_IDX(info, y, file_stats_t *);
+ int block_count = file_info->read_map->nelts;
for (x = 0; x < xsize; ++x)
{
- byte color[3] = { 128, 128, 128 };
- if (x < file_info->read_map->nelts)
+ color_t color = { 128, 128, 128 };
+ if (x < block_count)
{
word count = APR_ARRAY_IDX(file_info->read_map, x, word);
select_color(color, count);
}
- written = sizeof(color);
- apr_file_write(file, color, &written);
+ memcpy(line[x], color, sizeof(color));
}
- if (padding)
- {
- char pad[3] = { 0 };
- written = padding;
- apr_file_write(file, pad, &written);
- }
+ scale_line(scaled_line, max_x, line, block_count ? block_count : 1);
+
+ written = row_size;
+ apr_file_write(file, do_scale ? scaled_line : line, &written);
}
}
@@ -680,7 +751,13 @@ int main(int argc, const char *argv[])
apr_file_open(&file, "access.bmp",
APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BUFFERED,
APR_OS_DEFAULT, pool);
- write_bitmap(get_rev_files(pool), file);
+ write_bitmap(get_rev_files(pool), 0, file, pool);
+ apr_file_close(file);
+
+ apr_file_open(&file, "access_scaled.bmp",
+ APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BUFFERED,
+ APR_OS_DEFAULT, pool);
+ write_bitmap(get_rev_files(pool), 1024, file, pool);
apr_file_close(file);
apr_file_open(&file, "scale.bmp",