/* PSPP - a program for statistical analysis.
- Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <config.h>
-#include <libpspp/sparse-xarray.h>
+#include "libpspp/sparse-xarray.h"
+#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <libpspp/assertion.h>
-#include <libpspp/misc.h>
-#include <libpspp/range-set.h>
-#include <libpspp/sparse-array.h>
-#include <libpspp/tmpfile.h>
+#include "libpspp/assertion.h"
+#include "libpspp/ext-array.h"
+#include "libpspp/misc.h"
+#include "libpspp/range-set.h"
+#include "libpspp/sparse-array.h"
-#include "md4.h"
-#include "minmax.h"
-#include "xalloc.h"
+#include "gl/md4.h"
+#include "gl/minmax.h"
+#include "gl/xalloc.h"
/* A sparse array of arrays of bytes. */
struct sparse_xarray
uint8_t *default_row; /* Defaults for unwritten rows. */
unsigned long int max_memory_rows; /* Max rows before dumping to disk. */
struct sparse_array *memory; /* Backing, if stored in memory. */
- struct tmpfile *disk; /* Backing, if stored on disk. */
+ struct ext_array *disk; /* Backing, if stored on disk. */
struct range_set *disk_rows; /* Allocated rows, if on disk. */
};
const struct range_set_node *node;
void *tmp = xmalloc (old->n_bytes);
- new->disk = tmpfile_create ();
+ new->disk = ext_array_create ();
new->disk_rows = range_set_clone (old->disk_rows, NULL);
- for (node = range_set_first (old->disk_rows); node != NULL;
- node = range_set_next (old->disk_rows, node))
+ RANGE_SET_FOR_EACH (node, old->disk_rows)
{
unsigned long int start = range_set_node_get_start (node);
unsigned long int end = range_set_node_get_end (node);
for (idx = start; idx < end; idx++)
{
off_t offset = (off_t) idx * old->n_bytes;
- if (!tmpfile_read (old->disk, offset, old->n_bytes, tmp)
- || !tmpfile_write (new->disk, offset, old->n_bytes, tmp))
+ if (!ext_array_read (old->disk, offset, old->n_bytes, tmp)
+ || !ext_array_write (new->disk, offset, old->n_bytes, tmp))
{
free (tmp);
sparse_xarray_destroy (new);
return new;
}
+static void
+free_memory_rows (struct sparse_xarray *sx)
+{
+ if (sx->memory != NULL)
+ {
+ unsigned long int idx;
+ uint8_t **row;
+ for (row = sparse_array_first (sx->memory, &idx); row != NULL;
+ row = sparse_array_next (sx->memory, idx, &idx))
+ free (*row);
+ sparse_array_destroy (sx->memory);
+ sx->memory = NULL;
+ }
+}
+
/* Destroys sparse array of rows SX. */
void
sparse_xarray_destroy (struct sparse_xarray *sx)
if (sx != NULL)
{
free (sx->default_row);
- if (sx->memory != NULL)
- {
- unsigned long int idx;
- uint8_t **row;
- for (row = sparse_array_first (sx->memory, &idx); row != NULL;
- row = sparse_array_next (sx->memory, idx, &idx))
- free (*row);
- sparse_array_destroy (sx->memory);
- }
- tmpfile_destroy (sx->disk);
+ free_memory_rows (sx);
+ ext_array_destroy (sx->disk);
range_set_destroy (sx->disk_rows);
free (sx);
}
assert (sx->memory != NULL);
assert (sx->disk == NULL);
- sx->disk = tmpfile_create ();
+ sx->disk = ext_array_create ();
sx->disk_rows = range_set_create ();
for (row = sparse_array_first (sx->memory, &idx); row != NULL;
row = sparse_array_next (sx->memory, idx, &idx))
{
- if (!tmpfile_write (sx->disk, (off_t) idx * sx->n_bytes, sx->n_bytes,
+ if (!ext_array_write (sx->disk, (off_t) idx * sx->n_bytes, sx->n_bytes,
*row))
{
- tmpfile_destroy (sx->disk);
+ ext_array_destroy (sx->disk);
sx->disk = NULL;
range_set_destroy (sx->disk_rows);
sx->disk_rows = NULL;
return false;
}
- range_set_insert (sx->disk_rows, idx, 1);
+ range_set_set1 (sx->disk_rows, idx, 1);
}
- sparse_array_destroy (sx->memory);
- sx->memory = NULL;
+ free_memory_rows (sx);
return true;
}
else
{
if (range_set_contains (sx->disk_rows, row))
- return tmpfile_read (sx->disk, (off_t) row * sx->n_bytes + start,
- n, data);
+ return ext_array_read (sx->disk, (off_t) row * sx->n_bytes + start,
+ n, data);
}
memcpy (data, sx->default_row + start, n);
{
off_t ofs = (off_t) row * sx->n_bytes;
if (range_set_contains (sx->disk_rows, row))
- return tmpfile_write (sx->disk, ofs + start, n, data);
+ return ext_array_write (sx->disk, ofs + start, n, data);
else
{
- range_set_insert (sx->disk_rows, row, 1);
- return (tmpfile_write (sx->disk, ofs, start, sx->default_row)
- && tmpfile_write (sx->disk, ofs + start, n, data)
- && tmpfile_write (sx->disk, ofs + start + n,
- sx->n_bytes - start - n,
- sx->default_row + start + n));
+ range_set_set1 (sx->disk_rows, row, 1);
+ return (ext_array_write (sx->disk, ofs, start, sx->default_row)
+ && ext_array_write (sx->disk, ofs + start, n, data)
+ && ext_array_write (sx->disk, ofs + start + n,
+ sx->n_bytes - start - n,
+ sx->default_row + start + n));
}
}
{
const struct range_set_node *node;
- for (node = range_set_first (sx->disk_rows); node != NULL;
- node = range_set_next (sx->disk_rows, node))
+ RANGE_SET_FOR_EACH (node, sx->disk_rows)
{
unsigned long int start_row = range_set_node_get_start (node);
unsigned long int end_row = range_set_node_get_end (node);
for (row = start_row; row < end_row; row++)
{
off_t offset = (off_t) row * sx->n_bytes;
- if (!tmpfile_write (sx->disk, offset + start, n, data))
+ if (!ext_array_write (sx->disk, offset + start, n, data))
break;
}
}
- if (tmpfile_error (sx->disk))
+ if (ext_array_error (sx->disk))
return false;
}
return true;
uint8_t **p = sparse_array_get (sx->memory, idx);
return *p;
}
- else if (tmpfile_read (sx->disk, (off_t) idx * sx->n_bytes,
- sx->n_bytes, buffer))
+ else if (ext_array_read (sx->disk, (off_t) idx * sx->n_bytes,
+ sx->n_bytes, buffer))
return buffer;
else
return NULL;
const struct range_set_node *node;
void *tmp = xmalloc (sx->n_bytes);
- for (node = range_set_first (sx->disk_rows); node != NULL;
- node = range_set_next (sx->disk_rows, node))
+ RANGE_SET_FOR_EACH (node, sx->disk_rows)
{
unsigned long int start = range_set_node_get_start (node);
unsigned long int end = range_set_node_get_end (node);
for (row = start; row < end; row++)
{
off_t offset = (off_t) row * sx->n_bytes;
- success = (tmpfile_read (sx->disk, offset, sx->n_bytes, tmp)
+ success = (ext_array_read (sx->disk, offset, sx->n_bytes,
+ tmp)
&& cb (tmp, tmp, aux)
- && tmpfile_write (dx->disk, offset,
- dx->n_bytes, tmp));
+ && ext_array_write (dx->disk, offset,
+ dx->n_bytes, tmp));
if (!success)
break;
}
void *tmp = xmalloc (sx->n_bytes);
md4_process_bytes ("d", 1, &ctx);
- for (node = range_set_first (sx->disk_rows); node != NULL;
- node = range_set_next (sx->disk_rows, node))
+ RANGE_SET_FOR_EACH (node, sx->disk_rows)
{
unsigned long int start = range_set_node_get_start (node);
unsigned long int end = range_set_node_get_end (node);
for (idx = start; idx < end; idx++)
{
off_t offset = (off_t) idx * sx->n_bytes;
- if (!tmpfile_read (sx->disk, offset, sx->n_bytes, tmp))
+ if (!ext_array_read (sx->disk, offset, sx->n_bytes, tmp))
NOT_REACHED ();
md4_process_bytes (&idx, sizeof idx, &ctx);
md4_process_bytes (tmp, sx->n_bytes, &ctx);