/* fsfs-access-map.c -- convert strace output into FSFS access bitmap
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include "svn_pools.h"
#include "svn_string.h"
#include "svn_io.h"

#include "private/svn_string_private.h"

/* The information we gather for each file.  There will be one instance
 * per file name - even if the file got deleted and re-created.
 */
typedef struct file_stats_t
{
  /* file name as found in the open() call */
  const char *name;

  /* file size as determined during the this tool run.  Will be 0 for
   * files that no longer exist.  However, there may still be entries
   * in the read_map. */
  apr_int64_t size;

  /* for rev files (packed or non-packed), this will be the first revision
   * that file. -1 for non-rev files. */
  apr_int64_t rev_num;

  /* number of times this file got opened */
  apr_int64_t open_count;

  /* number of lseek counts */
  apr_int64_t seek_count;

  /* number of lseek calls to clusters not previously read */
  apr_int64_t uncached_seek_count;

  /* number of lseek counts not followed by a read */
  apr_int64_t unnecessary_seeks;

  /* number of read() calls */
  apr_int64_t read_count;

  /* number of read() calls that returned 0 bytes */
  apr_int64_t empty_reads;

  /* total number of bytes returned by those reads */
  apr_int64_t read_size;

  /* number of clusters read */
  apr_int64_t clusters_read;

  /* number of different clusters read
   * (i.e. number of non-zero entries in read_map). */
  apr_int64_t unique_clusters_read;

  /* cluster -> read count mapping (1 word per cluster, saturated at 64k) */
  apr_array_header_t *read_map;

} file_stats_t;

/* Represents an open file handle.  It refers to a file and concatenates
 * consecutive reads such that we don't artificially hit the same cluster
 * multiple times.  Instances of this type will be reused to limit the
 * allocation load on the lookup map.
 */
typedef struct handle_info_t
{
  /* the open file */
  file_stats_t *file;

  /* file offset at which the current series of reads started (default: 0) */
  apr_int64_t last_read_start;

  /* bytes read so far in the current series of reads started (default: 0) */
  apr_int64_t last_read_size;

  /* number of read() calls in this series */
  apr_int64_t read_count;
} handle_info_t;

/* useful typedef */
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;

/* global int handle -> *handle_info_t map.  Entries don't get removed
 * by close().  Instead, we simply recycle (and re-initilize) existing
 * instances. */
static apr_hash_t *handles = NULL;

/* assume cluster size.  64 and 128kB are typical values for RAIDs. */
static apr_int64_t cluster_size = 64 * 1024;

/* Call this after a sequence of reads has been ended by either close()
 * or lseek() for this HANDLE_INFO.  This will update the read_map and
 * unique_clusters_read members of the underlying file_info_t structure.
 */
static void
store_read_info(handle_info_t *handle_info)
{
  if (handle_info->last_read_size)
    {
      apr_size_t i;
      apr_size_t first_cluster
         = (apr_size_t)(handle_info->last_read_start / cluster_size);
      apr_size_t last_cluster
         = (apr_size_t)((  handle_info->last_read_start
                         + handle_info->last_read_size
                         - 1) / cluster_size);

      /* auto-expand access map in case the file later shrunk or got deleted */
      while (handle_info->file->read_map->nelts <= last_cluster)
        APR_ARRAY_PUSH(handle_info->file->read_map, word) = 0;

      /* accumulate the accesses per cluster. Saturate and count first
       * (i.e. disjoint) accesses clusters */
      handle_info->file->clusters_read += last_cluster - first_cluster + 1;
      for (i = first_cluster; i <= last_cluster; ++i)
        {
          word *count = &APR_ARRAY_IDX(handle_info->file->read_map, i, word);
          if (*count == 0)
            handle_info->file->unique_clusters_read++;
          if (*count < 0xffff)
            ++*count;
        }
    }
  else if (handle_info->read_count == 0)
    {
      /* two consecutive seeks */
      handle_info->file->unnecessary_seeks++;
    }
}

/* Handle a open() call.  Ensures that a file_info_t for the given NAME
 * exists.  Auto-create and initialize a handle_info_t for it linked to
 * HANDLE.
 */
static void
open_file(const char *name, int handle)
{
  file_stats_t *file = apr_hash_get(files, name, APR_HASH_KEY_STRING);
  handle_info_t *handle_info = apr_hash_get(handles, &handle, sizeof(handle));

  /* auto-create file info */
  if (!file)
    {
      apr_pool_t *pool = apr_hash_pool_get(files);
      apr_pool_t *subpool = svn_pool_create(pool);

      apr_file_t *apr_file = NULL;
      apr_finfo_t finfo = { 0 };
      int cluster_count = 0;

      /* determine file size (if file still exists) */
      apr_file_open(&apr_file, name,
                    APR_READ | APR_BUFFERED, APR_OS_DEFAULT, subpool);
      if (apr_file)
        apr_file_info_get(&finfo, APR_FINFO_SIZE, apr_file);
      svn_pool_destroy(subpool);

      file = apr_pcalloc(pool, sizeof(*file));
      file->name = apr_pstrdup(pool, name);
      file->size = finfo.size;

      /* pre-allocate cluster map accordingly
       * (will be auto-expanded later if necessary) */
      cluster_count = (int)(1 + (file->size - 1) / cluster_size);
      file->read_map = apr_array_make(pool, file->size
                                          ? cluster_count
                                          : 1, sizeof(word));

      while (file->read_map->nelts < cluster_count)
        APR_ARRAY_PUSH(file->read_map, byte) = 0;

      /* determine first revision of rev / packed rev files */
      if (strstr(name, "/db/revs/") != NULL && strstr(name, "manifest") == NULL)
        if (strstr(name, ".pack/pack") != NULL)
          file->rev_num = SVN_STR_TO_REV(strstr(name, "/db/revs/") + 9);
        else
          file->rev_num = SVN_STR_TO_REV(strrchr(name, '/') + 1);
      else
        file->rev_num = -1;

      /* filter out log/phys index files */
      if (file->rev_num >= 0)
        {
          const char *suffix = name + strlen(name) - 4;
          if (strcmp(suffix, ".l2p") == 0 || strcmp(suffix, ".p2l") == 0)
            file->rev_num = -1;
        }

      apr_hash_set(files, file->name, APR_HASH_KEY_STRING, file);
    }

  file->open_count++;

  /* auto-create handle instance */
  if (!handle_info)
    {
      apr_pool_t *pool = apr_hash_pool_get(handles);
      int *key = apr_palloc(pool, sizeof(*key));
      *key = handle;

      handle_info = apr_pcalloc(pool, sizeof(*handle_info));
      apr_hash_set(handles, key, sizeof(*key), handle_info);
    }

  /* link handle to file */
  handle_info->file = file;
  handle_info->last_read_start = 0;
  handle_info->last_read_size = 0;
}

/* COUNT bytes have been read from file with the given HANDLE.
 */
static void
read_file(int handle, apr_int64_t count)
{
  handle_info_t *handle_info = apr_hash_get(handles, &handle, sizeof(handle));
  if (handle_info)
    {
      /* known file handle -> expand current read sequence */

      handle_info->read_count++;
      handle_info->last_read_size += count;
      handle_info->file->read_count++;
      handle_info->file->read_size += count;

      if (count == 0)
        handle_info->file->empty_reads++;
    }
}

/* Seek to offset LOCATION in file given by HANDLE.
 */
static void
seek_file(int handle, apr_int64_t location)
{
  handle_info_t *handle_info = apr_hash_get(handles, &handle, sizeof(handle));
  if (handle_info)
    {
      /* known file handle -> end current read sequence and start a new one */

      apr_size_t cluster = (apr_size_t)(location / cluster_size);

      store_read_info(handle_info);

      handle_info->last_read_size = 0;
      handle_info->last_read_start = location;
      handle_info->read_count = 0;
      handle_info->file->seek_count++;

      /* if we seek to a location that had not been read from before,
       * there will probably be a real I/O seek on the following read.
       */
      if (   handle_info->file->read_map->nelts <= cluster
          || APR_ARRAY_IDX(handle_info->file->read_map, cluster, word) == 0)
        handle_info->file->uncached_seek_count++;
    }
}

/* The given file HANDLE has been closed.
 */
static void
close_file(int handle)
{
  /* for known file handles, end current read sequence */

  handle_info_t *handle_info = apr_hash_get(handles, &handle, sizeof(handle));
  if (handle_info)
    store_read_info(handle_info);
}

/* Parse / process non-empty the LINE from an strace output.
 */
static void
parse_line(svn_stringbuf_t *line)
{
  /* determine function name, first parameter and return value */
  char *func_end = strchr(line->data, '(');
  char *return_value = strrchr(line->data, ' ');
  char *first_param_end;
  apr_int64_t func_return = 0;
  char *func_start = strchr(line->data, ' ');

  if (func_end == NULL || return_value == NULL)
    return;

  if (func_start == NULL || func_start > func_end)
    func_start = line->data;
  else
    while(*func_start == ' ')
      func_start++;

  first_param_end = strchr(func_end, ',');
  if (first_param_end == NULL)
    first_param_end = strchr(func_end, ')');

  if (first_param_end == NULL)
    return;

  *func_end++ = 0;
  *first_param_end = 0;
  ++return_value;

  /* (try to) convert the return value into an integer.
   * If that fails, continue anyway as defaulting to 0 will be safe for us. */
  svn_error_clear(svn_cstring_atoi64(&func_return, return_value));

  /* process those operations that we care about */
  if (strcmp(func_start, "open") == 0)
    {
      /* remove double quotes from file name parameter */
      *func_end++ = 0;
      *--first_param_end = 0;

      open_file(func_end, (int)func_return);
    }
  else if (strcmp(func_start, "read") == 0)
    read_file(atoi(func_end), func_return);
  else if (strcmp(func_start, "lseek") == 0)
    seek_file(atoi(func_end), func_return);
  else if (strcmp(func_start, "close") == 0)
    close_file(atoi(func_end));
}

/* Process the strace output stored in FILE.
 */
static void
parse_file(apr_file_t *file)
{
  apr_pool_t *pool = svn_pool_create(NULL);
  apr_pool_t *iterpool = svn_pool_create(pool);

  /* limit lines to 4k (usually, we need less than 200 bytes) */
  svn_stringbuf_t *line = svn_stringbuf_create_ensure(4096, pool);

  do
    {
      svn_error_t *err = NULL;

      line->len = line->blocksize-1;
      err = svn_io_read_length_line(file, line->data, &line->len, iterpool);
      svn_error_clear(err);
      if (err)
        break;

      parse_line(line);
      svn_pool_clear(iterpool);
    }
  while (line->len > 0);
}

/* qsort() callback.  Sort files by revision number.
 */
static int
compare_files(file_stats_t **lhs, file_stats_t **rhs)
{
  return (*lhs)->rev_num < (*rhs)->rev_num;
}

/* Return all rev (and packed rev) files sorted by revision number.
 * Allocate the result in POOL.
 */
static apr_array_header_t *
get_rev_files(apr_pool_t *pool)
{
  apr_hash_index_t *hi;
  apr_array_header_t *result = apr_array_make(pool,
                                              apr_hash_count(files),
                                              sizeof(file_stats_t *));

  /* select all files that have a rev number */
  for (hi = apr_hash_first(pool, files); hi; hi = apr_hash_next(hi))
    {
      const char *name = NULL;
      apr_ssize_t len = 0;
      file_stats_t *file = NULL;

      apr_hash_this(hi, (const void **)&name, &len, (void**)&file);
      if (file->rev_num >= 0)
        APR_ARRAY_PUSH(result, file_stats_t *) = file;
    }

  /* sort them */
  qsort(result->elts, result->nelts, result->elt_size,
        (int (*)(const void *, const void *))compare_files);

  /* return the result */
  return result;
}

/* store VALUE to DEST in little-endian format.  Assume that the target
 * buffer is filled with 0.
 */
static void
write_number(byte *dest, int value)
{
  while (value)
    {
      *dest = (byte)(value % 256);
      value /= 256;
      ++dest;
    }
}

/* Return a linearly interpolated y value for X with X0 <= X <= X1 and
 * the corresponding Y0 and Y1 values.
 */
static int
interpolate(int y0, int x0, int y1, int x1, int x)
{
  return y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);
}

/* Return the BMP-encoded 24 bit COLOR for the given value.
 */
static void
select_color(byte color[3], word value)
{
  enum { COLOR_COUNT = 10 };

  /* value -> color table. Missing values get interpolated.
   * { count, B - G - R } */
  word table[COLOR_COUNT][4] =
    {
      {     0, 255, 255, 255 },   /* unread -> white */
      {     1,  64, 128,   0 },   /* read once -> turquoise  */
      {     2,   0, 128,   0 },   /* twice  -> green */
      {     8,   0, 192, 192 },   /*    8x  -> yellow */
      {    64,   0,   0, 192 },   /*   64x  -> red */
      {   256,  64,  32, 230 },   /*  256x  -> bright red */
      {   512, 192,   0, 128 },   /*  512x  -> purple */
      {  1024,  96,  32,  96 },   /* 1024x  -> UV purple */
      {  4096,  32,  16,  32 },   /* 4096x  -> EUV purple */
      { 65535,   0,   0,   0 }    /*   max  -> black */
    };

  /* find upper limit entry for value */
  int i;
  for (i = 0; i < COLOR_COUNT; ++i)
    if (table[i][0] >= value)
      break;

  /* exact match? */
  if (table[i][0] == value)
    {
      color[0] = (byte)table[i][1];
      color[1] = (byte)table[i][2];
      color[2] = (byte)table[i][3];
    }
  else
    {
      /* interpolate */
      color[0] = (byte)interpolate(table[i-1][1], table[i-1][0],
                                   table[i][1], table[i][0],
                                   value);
      color[1] = (byte)interpolate(table[i-1][2], table[i-1][0],
                                   table[i][2], table[i][0],
                                   value);
      color[2] = (byte)interpolate(table[i-1][3], table[i-1][0],
                                   table[i][3], table[i][0],
                                   value);
    }
}

/* Writes a BMP image header to FILE for a 24-bit color picture of the
 * given XSIZE and YSIZE dimension.
 */
static void
write_bitmap_header(apr_file_t *file, int xsize, int ysize)
{
  /* BMP file header (some values need to filled in later)*/
  byte header[54] =
    {
      'B', 'M',        /* magic */
      0, 0, 0, 0,      /* file size (to be written later) */
      0, 0, 0, 0,      /* reserved, unused */
      54, 0, 0, 0,     /* pixel map starts at offset 54dec */

      40, 0, 0, 0,     /* DIB header has 40 bytes */
      0, 0, 0, 0,      /* x size in pixel */
      0, 0, 0, 0,      /* y size in pixel */
      1, 0,            /* 1 color plane */
      24, 0,           /* 24 bits / pixel */
      0, 0, 0, 0,      /* no pixel compression used */
      0, 0, 0, 0,      /* size of pixel array (to be written later) */
      0xe8, 3, 0, 0,   /* 1 pixel / mm */
      0xe8, 3, 0, 0,   /* 1 pixel / mm */
      0, 0, 0, 0,      /* no colors in palette */
      0, 0, 0, 0       /* no colors to import */
    };

  apr_size_t written;

  /* rows in BMP files must be aligned to 4 bytes */
  int row_size = APR_ALIGN(xsize * 3, 4);

  /* write numbers to header */
  write_number(header + 2, ysize * row_size + 54);
  write_number(header + 18, xsize);
  write_number(header + 22, ysize);
  write_number(header + 38, ysize * row_size);

  /* write header to file */
  written = sizeof(header);
  apr_file_write(file, header, &written);
}

/* 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,
           int out_len,
           color_t *in,
           int 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,
             int max_x,
             apr_file_t *file,
             apr_pool_t *pool)
{
  int ysize = info->nelts;
  int xsize = 0;
  int x, y;
  apr_size_t row_size;
  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)
    if (xsize < APR_ARRAY_IDX(info, y, file_stats_t *)->read_map->nelts)
      xsize = APR_ARRAY_IDX(info, y, file_stats_t *)->read_map->nelts;

  /* limit picture dimensions (16k pixels in each direction) */
  if (xsize >= 0x4000)
    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(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, 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)
        {
          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);
            }

          memcpy(line[x], color, sizeof(color));
        }

      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);
    }
}

/* write a color bar with (roughly) logarithmic scale as BMP image to FILE.
 */
static void
write_scale(apr_file_t *file)
{
  int x;
  word value = 0, inc = 1;

  /* write header to file */
  write_bitmap_header(file, 64, 1);

  for (x = 0; x < 64; ++x)
    {
      apr_size_t written;
      byte color[3] = { 128, 128, 128 };

      select_color(color, value);
      if (value + (int)inc < 0x10000)
        {
          value += inc;
          if (value >= 8 * inc)
            inc *= 2;
        }

      written = sizeof(color);
      apr_file_write(file, color, &written);
    }
}

/* Write a summary of the I/O ops to stdout.
 * Use POOL for temporaries.
 */
static void
print_stats(apr_pool_t *pool)
{
  apr_int64_t open_count = 0;
  apr_int64_t seek_count = 0;
  apr_int64_t read_count = 0;
  apr_int64_t read_size = 0;
  apr_int64_t clusters_read = 0;
  apr_int64_t unique_clusters_read = 0;
  apr_int64_t uncached_seek_count = 0;
  apr_int64_t unnecessary_seek_count = 0;
  apr_int64_t empty_read_count = 0;

  apr_hash_index_t *hi;
  for (hi = apr_hash_first(pool, files); hi; hi = apr_hash_next(hi))
    {
      const char *name = NULL;
      apr_ssize_t len = 0;
      file_stats_t *file = NULL;

      apr_hash_this(hi, (const void **)&name, &len, (void**)&file);

      open_count += file->open_count;
      seek_count += file->seek_count;
      read_count += file->read_count;
      read_size += file->read_size;
      clusters_read += file->clusters_read;
      unique_clusters_read += file->unique_clusters_read;
      uncached_seek_count += file->uncached_seek_count;
      unnecessary_seek_count += file->unnecessary_seeks;
      empty_read_count += file->empty_reads;
    }

  printf("%20s files\n", svn__i64toa_sep(apr_hash_count(files), ',', pool));
  printf("%20s files opened\n", svn__i64toa_sep(open_count, ',', pool));
  printf("%20s seeks\n", svn__i64toa_sep(seek_count, ',', pool));
  printf("%20s unnecessary seeks\n", svn__i64toa_sep(unnecessary_seek_count, ',', pool));
  printf("%20s uncached seeks\n", svn__i64toa_sep(uncached_seek_count, ',', pool));
  printf("%20s reads\n", svn__i64toa_sep(read_count, ',', pool));
  printf("%20s empty reads\n", svn__i64toa_sep(empty_read_count, ',', pool));
  printf("%20s unique clusters read\n", svn__i64toa_sep(unique_clusters_read, ',', pool));
  printf("%20s clusters read\n", svn__i64toa_sep(clusters_read, ',', pool));
  printf("%20s bytes read\n", svn__i64toa_sep(read_size, ',', pool));
}

/* Some help output. */
static void
print_usage(void)
{
  printf("fsfs-access-map <file>\n\n");
  printf("Reads strace of some FSFS-based tool from <file>, prints some stats\n");
  printf("and writes a cluster access map to 'access.bmp' the current folder.\n");
  printf("Each pixel corresponds to one 64kB cluster and every line to a rev\n");
  printf("or packed rev file in the repository.  Turquoise and green indicate\n");
  printf("1 and 2 hits, yellow to read-ish colors for up to 20, shares of\n");
  printf("for up to 100 and black for > 200 hits.\n\n");
  printf("A typical strace invocation looks like this:\n");
  printf("strace -e trace=open,close,read,lseek -o strace.txt svn log ...\n");
}

/* linear control flow */
int main(int argc, const char *argv[])
{
  apr_pool_t *pool = NULL;
  apr_file_t *file = NULL;

  apr_initialize();
  atexit(apr_terminate);

  pool = svn_pool_create(NULL);
  files = apr_hash_make(pool);
  handles = apr_hash_make(pool);

  if (argc == 2)
    apr_file_open(&file, argv[1], APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
                  pool);
  if (file == NULL)
    {
      print_usage();
      return 0;
    }
  parse_file(file);
  apr_file_close(file);

  print_stats(pool);

  apr_file_open(&file, "access.bmp",
                APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BUFFERED,
                APR_OS_DEFAULT, pool);
  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",
                APR_WRITE | APR_CREATE | APR_TRUNCATE | APR_BUFFERED,
                APR_OS_DEFAULT, pool);
  write_scale(file);
  apr_file_close(file);

  return 0;
}
