gegl r2204 - in trunk: . gegl/buffer
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2204 - in trunk: . gegl/buffer
- Date: Sun, 20 Apr 2008 13:10:23 +0100 (BST)
Author: ok
Date: Sun Apr 20 12:10:23 2008
New Revision: 2204
URL: http://svn.gnome.org/viewvc/gegl?rev=2204&view=rev
Log:
* gegl/buffer/gegl-buffer-access.c: (gegl_buffer_flush): invoke the
flush command for the tile infrastructure.
* gegl/buffer/gegl-buffer-index.h: include guards, and added some of
the new private functions from gegl-buffer-save.c
* gegl/buffer/gegl-buffer-load.c: (seekto), (read_header),
(read_block), (gegl_buffer_load): made the loader a bit more tolerant
to nonsequential files, not fully tested.
* gegl/buffer/gegl-buffer-private.h: moved gegl_buffer_flush() ..
* gegl/buffer/gegl-buffer.h: .. here
* gegl/buffer/gegl-buffer-save.c: (gegl_tile_entry_new),
(gegl_tile_entry_destroy), (save_info_destroy),
(gegl_buffer_header_init), (gegl_buffer_save): made some of the struct
preparation code sharable.
* gegl/buffer/gegl-tile-backend-file.c: make use of shared
types from gegl-buffer-index.h for the tile index.
* gegl/buffer/gegl-tile-handler-cache.c: (command): tell all tiles in
our cache to store themself.
* gegl/buffer/gegl-tile-handler-log.c: added flush command.
* gegl/buffer/gegl-tile-source.h: added flush command.
Modified:
trunk/ChangeLog
trunk/gegl/buffer/gegl-buffer-access.c
trunk/gegl/buffer/gegl-buffer-index.h
trunk/gegl/buffer/gegl-buffer-load.c
trunk/gegl/buffer/gegl-buffer-private.h
trunk/gegl/buffer/gegl-buffer-save.c
trunk/gegl/buffer/gegl-buffer.h
trunk/gegl/buffer/gegl-tile-backend-file.c
trunk/gegl/buffer/gegl-tile-handler-cache.c
trunk/gegl/buffer/gegl-tile-handler-log.c
trunk/gegl/buffer/gegl-tile-source.h
Modified: trunk/gegl/buffer/gegl-buffer-access.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-access.c (original)
+++ trunk/gegl/buffer/gegl-buffer-access.c Sun Apr 20 12:10:23 2008
@@ -33,6 +33,9 @@
#include "gegl-sampler-linear.h"
#include "gegl-sampler-cubic.h"
+#if ENABLE_MP
+GStaticRecMutex mutex = G_STATIC_REC_MUTEX_INIT;
+#endif
#ifdef BABL
@@ -291,6 +294,8 @@
g_object_unref (buffer->hot_tile);
buffer->hot_tile = NULL;
}
+ gegl_tile_source_command (GEGL_TILE_SOURCE (buffer),
+ GEGL_TILE_FLUSH, 0,0,0,NULL);
}
Modified: trunk/gegl/buffer/gegl-buffer-index.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-index.h (original)
+++ trunk/gegl/buffer/gegl-buffer-index.h Sun Apr 20 12:10:23 2008
@@ -1,3 +1,5 @@
+#ifndef __GEGL_BUFFER_INDEX_H
+#define __GEGL_BUFFER_INDEX_H
/* File format building blocks
GeglBuffer on disk representation
@@ -11,7 +13,6 @@
#define GEGL_FLAG_TILE_IS_FREE 4
#define GEGL_FLAG_TILE_FREE (GEGL_FLAG_TILE|GEGL_FLAG_TILE_IS_FREE)
-
/*
* This header is the first 256 bytes of the GEGL buffer.
*/
@@ -54,15 +55,31 @@
/* The header is followed by elements describing tiles stored in the swap,
*/
typedef struct {
- GeglBufferBlock blockdef; /* The block definition for this tile entry */
- gint32 x; /* upperleft of tile % tile_width coordinates */
+ GeglBufferBlock block; /* The block definition for this tile entry */
+ gint32 x; /* upperleft of tile % tile_width coordinates */
gint32 y;
- gint32 z; /* mipmap subdivision level of tile (0=100%) */
- guint64 offset; /* offset into file for this tile */
+ gint32 z; /* mipmap subdivision level of tile (0=100%) */
+ guint64 offset; /* offset into file for this tile */
guint32 padding[23];
} GeglBufferTile;
+GeglBufferTile *
+gegl_tile_entry_new (gint x,
+ gint y,
+ gint z);
+
+
+void
+gegl_buffer_header_init (GeglBufferHeader *header,
+ gint tile_width,
+ gint tile_height,
+ gint bpp,
+ Babl* format);
+
+void
+gegl_tile_entry_destroy (GeglBufferTile *entry);
+
/* A convenience union to allow quick and simple casting */
typedef union {
guint32 length;
@@ -87,3 +104,4 @@
struct_check_padding (GeglBufferTile, 128);}
#define GEGL_BUFFER_SANITY {static gboolean done=FALSE;if(!done){GEGL_BUFFER_STRUCT_CHECK_PADDING;done=TRUE;}}
+#endif
Modified: trunk/gegl/buffer/gegl-buffer-load.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-load.c (original)
+++ trunk/gegl/buffer/gegl-buffer-load.c Sun Apr 20 12:10:23 2008
@@ -42,6 +42,8 @@
#include "gegl-region.h"
#include "gegl-buffer-index.h"
+#include <glib/gprintf.h>
+
typedef struct
{
GeglBufferHeader header;
@@ -56,6 +58,13 @@
gboolean got_header;
} LoadInfo;
+static void seekto(LoadInfo *info, gint pos)
+{
+ info->pos = pos;
+ g_printf ("seek to %i\n", pos);
+ g_seekable_seek (G_SEEKABLE (info->i), info->pos, G_SEEK_SET, NULL, NULL);
+}
+
static GeglBufferItem *read_header (LoadInfo *info)
{
GeglBufferBlock block;
@@ -65,7 +74,7 @@
if (info->pos != 0)
{
- g_print ("%s must seek\n", G_STRFUNC);
+ seekto (info, 0);
}
info->pos += g_input_stream_read (info->i, &block, sizeof (GeglBufferBlock), NULL, NULL);
@@ -90,6 +99,8 @@
NULL, NULL);
}
info->next_block = ret->block.next;
+
+ g_printf ("header: next:%i\n", (guint)ret->block.next);
return ret;
}
@@ -99,9 +110,11 @@
GeglBufferBlock block;
GeglBufferItem *ret;
+ if (!info->next_block)
+ return NULL;
if (info->pos != info->next_block)
{
- g_print ("must seek\n");
+ seekto (info, info->next_block);
}
info->pos+= g_input_stream_read (info->i, &block, sizeof (GeglBufferBlock),
@@ -202,11 +215,15 @@
/* load the index */
{
- gint i;
- for (i = 0; i < info->header.entry_count; i++)
+ GeglBufferItem *item; /* = read_block (info);*/
+ for (item = read_block (info); item; item = read_block (info))
{
- GeglBufferItem *item = read_block (info);
g_assert (item);
+ g_print ("%i, %i, %i offset:%i next:%i\n", item->tile.x,
+ item->tile.y,
+ item->tile.z,
+ (guint)item->tile.offset,
+ (guint)item->block.next);
info->tiles = g_list_prepend (info->tiles, item);
}
info->tiles = g_list_reverse (info->tiles);
@@ -235,7 +252,7 @@
if (info->pos != entry->offset)
{
- g_warning ("%s must seek", G_STRFUNC);
+ seekto (info, entry->offset);
}
info->pos += g_input_stream_read (info->i, data, info->tile_size,
Modified: trunk/gegl/buffer/gegl-buffer-private.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-private.h (original)
+++ trunk/gegl/buffer/gegl-buffer-private.h Sun Apr 20 12:10:23 2008
@@ -77,10 +77,6 @@
const gchar *path,
const GeglRectangle *roi);
-/* flush any unwritten data (flushes the hot-cache of a single
- * tile used by gegl_buffer_set for 1x1 pixel sized rectangles
- */
-void gegl_buffer_flush (GeglBuffer *buffer);
const gchar * gegl_swap_dir (void);
Modified: trunk/gegl/buffer/gegl-buffer-save.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-save.c (original)
+++ trunk/gegl/buffer/gegl-buffer-save.c Sun Apr 20 12:10:23 2008
@@ -58,12 +58,14 @@
} SaveInfo;
-static GeglBufferTile *
-tile_entry_new (gint x,
- gint y,
- gint z)
+GeglBufferTile *
+gegl_tile_entry_new (gint x,
+ gint y,
+ gint z)
{
GeglBufferTile *entry = g_slice_new0 (GeglBufferTile);
+ entry->block.flags = GEGL_FLAG_TILE;
+ entry->block.length = sizeof (GeglBufferTile);
entry->x = x;
entry->y = y;
@@ -71,8 +73,8 @@
return entry;
}
-static void
-tile_entry_destroy (GeglBufferTile *entry)
+void
+gegl_tile_entry_destroy (GeglBufferTile *entry)
{
g_slice_free (GeglBufferTile, entry);
}
@@ -116,7 +118,7 @@
{
GList *iter;
for (iter = info->tiles; iter; iter = iter->next)
- tile_entry_destroy (iter->data);
+ gegl_tile_entry_destroy (iter->data);
g_list_free (info->tiles);
info->tiles = NULL;
}
@@ -162,6 +164,32 @@
}
+void
+gegl_buffer_header_init (GeglBufferHeader *header,
+ gint tile_width,
+ gint tile_height,
+ gint bpp,
+ Babl* format)
+{
+ strcpy (header->magic, "GEGL");
+
+ header->flags = GEGL_FLAG_HEADER;
+
+ header->tile_width = tile_width;
+ header->tile_height = tile_height;
+ header->bytes_per_pixel = bpp;
+ header->width = 256;
+ header->height = 256;
+ {
+ gchar buf[64];
+ g_snprintf (buf, 64, "%s%c\n%iÃ%i %ibpp\n\n\n\n\n\n\n\n\n\n",
+ format->instance.name, 0,
+ header->tile_width,
+ header->tile_height,
+ header->bytes_per_pixel);
+ memcpy ((header->description), buf, 64);
+ }
+}
void
gegl_buffer_save (GeglBuffer *buffer,
@@ -171,47 +199,27 @@
SaveInfo *info = g_slice_new0 (SaveInfo);
glong prediction = 0;
+ gint bpp;
GEGL_BUFFER_SANITY;
- strcpy (info->header.magic, "GEGL");
-
/* a header should follow the same structure as a blockdef with
* respect to the flags and next offsets, thus this is a valid
* cast shortcut.
*/
- info->header.flags = GEGL_FLAG_HEADER;
- info->header.next = (prediction += sizeof (GeglBufferHeader));
info->path = g_strdup (path);
info->file = g_file_new_for_commandline_arg (info->path);
info->o = G_OUTPUT_STREAM (g_file_replace (info->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
-#if 0
- if (info->fd == -1)
- {
- gchar *name = g_filename_display_name (info->path);
-
- g_message ("Unable to open '%s' when saving a buffer: %s",
- name, g_strerror (errno));
- g_free (name);
-
- save_info_destroy (info);
- return;
- }
-#endif
- info->header.tile_width = buffer->tile_storage->tile_width;
- info->header.tile_height = buffer->tile_storage->tile_height;
- g_object_get (buffer, "px-size", &(info->header.bytes_per_pixel), NULL);
- {
- gchar buf[64];
- g_snprintf (buf, 64, "%s%c\n%iÃ%i %ibpp\n\n\n\n\n\n\n\n\n\n",
- ((Babl *) (buffer->tile_storage->format))->instance.name, 0,
- info->header.tile_width,
- info->header.tile_height,
- info->header.bytes_per_pixel);
- memcpy (info->header.description, buf, 64);
- }
+ g_object_get (buffer, "px-size", &bpp, NULL);
+ gegl_buffer_header_init (&info->header,
+ buffer->tile_storage->tile_width,
+ buffer->tile_storage->tile_height,
+ bpp,
+ buffer->tile_storage->format
+ );
+ info->header.next = (prediction += sizeof (GeglBufferHeader));
info->header.x = buffer->extent.x;
info->header.y = buffer->extent.y;
@@ -267,9 +275,7 @@
{
GeglBufferTile *entry;
- entry = tile_entry_new (tx, ty, z);
- entry->blockdef.length = sizeof (GeglBufferTile);
- entry->blockdef.flags = GEGL_FLAG_TILE;
+ entry = gegl_tile_entry_new (tx, ty, z);
info->tiles = g_list_prepend (info->tiles, entry);
info->header.entry_count++;
}
@@ -298,8 +304,8 @@
for (iter = info->tiles; iter; iter = iter->next)
{
GeglBufferTile *entry = iter->data;
- entry->blockdef.next = iter->next?
- (prediction += sizeof (GeglBufferTile)):0;
+ entry->block.next = iter->next?
+ (prediction += sizeof (GeglBufferTile)):0;
entry->offset = predicted_offset;
predicted_offset += info->tile_size;
}
Modified: trunk/gegl/buffer/gegl-buffer.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer.h (original)
+++ trunk/gegl/buffer/gegl-buffer.h Sun Apr 20 12:10:23 2008
@@ -81,7 +81,7 @@
*/
GeglBuffer* gegl_buffer_open (const gchar *uri);
-
+void gegl_buffer_flush (GeglBuffer *buffer);
void
gegl_buffer_make_uri (gchar *buf_128,
Modified: trunk/gegl/buffer/gegl-tile-backend-file.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend-file.c (original)
+++ trunk/gegl/buffer/gegl-tile-backend-file.c Sun Apr 20 12:10:23 2008
@@ -23,202 +23,297 @@
#include <errno.h>
#include <glib-object.h>
+#include <glib/gprintf.h>
#include "gegl-tile-backend.h"
#include "gegl-tile-backend-file.h"
+#include "gegl-buffer-index.h"
+
struct _GeglTileBackendFile
{
GeglTileBackend parent_instance;
- gchar *path;
- GFile *file;
- GOutputStream *o;
- GInputStream *i;
- GHashTable *entries;
- GSList *free_list;
- guint next_unused;
- guint total;
+ gchar *path; /* the path to our buffer */
+ GFile *file; /* gfile refering to our buffer */
+ GOutputStream *o; /* for writing */
+ GInputStream *i; /* for reading */
+
+ /*gint fd;*/
+ GHashTable *index; /* hashtable containing all entries
+ * of buffer, the index is
+ * written to the swapfile conforming
+ * to the structures laid out in
+ * gegl-buffer-index.h
+ */
+
+ GSList *free_list; /* list of offsets to tiles that are free */
+
+ guint next_pre_alloc; /* offset to next pre allocated tile slot */
+ guint total; /* total size of file */
+
+ /* duplicated from gegl-buffer-save */
+
+ GeglBufferHeader header; /* a local copy of the header that will be
+ * written to the file, in a multiple user
+ * per buffer scenario, the flags in the
+ * header might be used for locking/signalling
+ */
+
+ gint offset; /* current offset, used when writing the
+ * index,
+ */
+ GeglBufferBlock *in_holding; /* when writing buffer blocks the writer
+ * keeps one block unwritten at all times
+ * to be able to keep track of the ->next
+ * offsets in the blocks.
+ */
};
-static void dbg_alloc (int size);
-static void dbg_dealloc (int size);
-/* These entries are kept in RAM for now, they should be written as an
- * index to the swap file, at a position specified by a header block,
- * making the header grow up to a multiple of the size used in this
- * swap file is probably a good idea
- *
- * Serializing the bablformat is probably also a good idea.
- */
-typedef struct _DiskEntry DiskEntry;
+static gboolean
+write_block (GeglTileBackendFile *self,
+ GeglBufferBlock *block);
-struct _DiskEntry
-{
- gint x;
- gint y;
- gint z;
- gint offset;
-};
+static void dbg_alloc (int size);
+static void dbg_dealloc (int size);
static void inline
-disk_entry_read (GeglTileBackendFile *disk,
- DiskEntry *entry,
+file_entry_read (GeglTileBackendFile *self,
+ GeglBufferTile *entry,
guchar *dest)
{
- gint nleft;
+ gint to_be_read;
gboolean success;
- gint tile_size = GEGL_TILE_BACKEND (disk)->tile_size;
+ gint tile_size = GEGL_TILE_BACKEND (self)->tile_size;
+ goffset offset = entry->offset; /* we need 64bit */
- success = g_seekable_seek (G_SEEKABLE (disk->i),
- (goffset) entry->offset * tile_size, G_SEEK_SET,
+ success = g_seekable_seek (G_SEEKABLE (self->i),
+ offset, G_SEEK_SET,
NULL, NULL);
if (success == FALSE)
{
g_warning ("unable to seek to tile in buffer: %s", g_strerror (errno));
return;
}
- nleft = tile_size;
+ to_be_read = tile_size;
- while (nleft > 0)
+ while (to_be_read > 0)
{
gint read;
- read = g_input_stream_read (G_INPUT_STREAM (disk->i),
- dest + tile_size - nleft, nleft,
+ read = g_input_stream_read (G_INPUT_STREAM (self->i),
+ dest + tile_size - to_be_read, to_be_read,
NULL, NULL);
if (read <= 0)
{
- g_message ("unable to read tile data from disk: "
+ g_message ("unable to read tile data from self: "
"%s (%d/%d bytes read)",
- g_strerror (errno), read, nleft);
+ g_strerror (errno), read, to_be_read);
return;
}
- nleft -= read;
+ to_be_read -= read;
}
}
static void inline
-disk_entry_write (GeglTileBackendFile *disk,
- DiskEntry *entry,
+file_entry_write (GeglTileBackendFile *self,
+ GeglBufferTile *entry,
guchar *source)
{
- gint nleft;
+ gint to_be_written;
gboolean success;
- gint tile_size = GEGL_TILE_BACKEND (disk)->tile_size;
+ gint tile_size = GEGL_TILE_BACKEND (self)->tile_size;
+ goffset offset = entry->offset; /* we need 64 bit */
- success = g_seekable_seek (G_SEEKABLE (disk->o),
- (goffset) entry->offset * tile_size, G_SEEK_SET,
+ success = g_seekable_seek (G_SEEKABLE (self->o),
+ offset, G_SEEK_SET,
NULL, NULL);
if (success == FALSE)
{
g_warning ("unable to seek to tile in buffer: %s", g_strerror (errno));
return;
}
- nleft = tile_size;
+ to_be_written = tile_size;
- while (nleft > 0)
+ while (to_be_written > 0)
{
gint wrote;
- wrote = g_output_stream_write (disk->o, source + tile_size - nleft,
- nleft, NULL, NULL);
+ wrote = g_output_stream_write (self->o,
+ source + tile_size - to_be_written,
+ to_be_written, NULL, NULL);
if (wrote <= 0)
{
- g_message ("unable to write tile data to disk: "
+ g_message ("unable to write tile data to self: "
"%s (%d/%d bytes written)",
- g_strerror (errno), wrote, nleft);
+ g_strerror (errno), wrote, to_be_written);
return;
}
- nleft -= wrote;
+ to_be_written -= wrote;
}
}
-static inline DiskEntry *
-disk_entry_new (GeglTileBackendFile *disk)
+static inline GeglBufferTile *
+file_entry_new (GeglTileBackendFile *self)
{
- DiskEntry *self = g_slice_new (DiskEntry);
+ GeglBufferTile *entry = gegl_tile_entry_new (0,0,0);
- if (disk->free_list)
+ if (self->free_list)
{
- self->offset = GPOINTER_TO_INT (disk->free_list->data);
- disk->free_list = g_slist_remove (disk->free_list, disk->free_list->data);
+ /* XXX: losing precision ? */
+ gint offset = GPOINTER_TO_INT (self->free_list->data);
+ entry->offset = offset;
+ self->free_list = g_slist_remove (self->free_list, self->free_list->data);
}
else
{
- self->offset = disk->next_unused++;
+ gint tile_size = GEGL_TILE_BACKEND (self)->tile_size;
- if (self->offset >= disk->total)
+ entry->offset = self->next_pre_alloc;
+ self->next_pre_alloc += tile_size;
+
+ if (self->next_pre_alloc >= self->total)
{
- gint grow = 32; /* grow 32 tiles of swap space at a time */
- gint tile_size = GEGL_TILE_BACKEND (disk)->tile_size;
- g_assert (g_seekable_truncate (G_SEEKABLE (disk->o),
- (goffset) (disk->total + grow) * (goffset) tile_size,
- NULL,NULL));
- disk->total = self->offset;
+ self->total = self->total + 32 * tile_size;
+
+ g_assert (g_seekable_truncate (G_SEEKABLE (self->o),
+ self->total, NULL,NULL));
}
}
- dbg_alloc (GEGL_TILE_BACKEND (disk)->tile_size);
- return self;
+ dbg_alloc (GEGL_TILE_BACKEND (self)->tile_size);
+ return entry;
}
static inline void
-disk_entry_destroy (DiskEntry *entry,
- GeglTileBackendFile *disk)
+file_entry_destroy (GeglBufferTile *entry,
+ GeglTileBackendFile *self)
{
- disk->free_list = g_slist_prepend (disk->free_list,
- GINT_TO_POINTER (entry->offset));
- g_hash_table_remove (disk->entries, entry);
+ /* XXX: EEEk, throwing away bits */
+ guint offset = entry->offset;
+ self->free_list = g_slist_prepend (self->free_list,
+ GUINT_TO_POINTER (offset));
+ g_hash_table_remove (self->index, entry);
- dbg_dealloc (GEGL_TILE_BACKEND (disk)->tile_size);
- g_slice_free (DiskEntry, entry);
+ dbg_dealloc (GEGL_TILE_BACKEND (self)->tile_size);
+ g_slice_free (GeglBufferTile, entry);
}
+static gboolean write_header (GeglTileBackendFile *self)
+{
+ gboolean success;
+ success = g_seekable_seek (G_SEEKABLE (self->o), 0, G_SEEK_SET,
+ NULL, NULL);
+ if (success == FALSE)
+ {
+ g_warning ("unable to seek in buffer");
+ return FALSE;
+ }
+ g_output_stream_write (self->o, &(self->header), 256, NULL, NULL);
+ return TRUE;
+}
+
+static gboolean
+write_block (GeglTileBackendFile *self,
+ GeglBufferBlock *block)
+{
+ if (self->in_holding)
+ {
+ guint64 next_allocation = self->offset + self->in_holding->length;
+
+ /* update the next offset pointer in the previous block */
+ self->in_holding->next = next_allocation;
+
+ if (block == NULL) /* the previous block was the last block */
+ {
+ self->in_holding->next = 0;
+ }
+
+ if(!g_seekable_seek (G_SEEKABLE (self->o),
+ self->offset, G_SEEK_SET,
+ NULL, NULL))
+ goto fail;
+
+ self->offset += g_output_stream_write (self->o, self->in_holding,
+ self->in_holding->length,
+ NULL, NULL);
+
+ g_assert (next_allocation == self->offset); /* true as long as
+ the simple allocation
+ scheme is used */
+
+ self->offset = next_allocation;
+ }
+ else
+ {
+ /* we're setting up for the first write */
+
+ self->offset = self->next_pre_alloc; /* start writing header at end
+ * of file, worry about writing
+ * header inside free list later
+ */
+
+ if(!g_seekable_seek (G_SEEKABLE (self->o),
+ (goffset) self->offset, G_SEEK_SET,
+ NULL, NULL))
+ goto fail;
+ }
+ self->in_holding = block;
+
+ return TRUE;
+fail:
+ g_warning ("gegl buffer index writing problems for %s",
+ self->path);
+ return FALSE;
+}
G_DEFINE_TYPE (GeglTileBackendFile, gegl_tile_backend_file, GEGL_TYPE_TILE_BACKEND)
static GObjectClass * parent_class = NULL;
+/* this debugging is across all buffers */
static gint allocs = 0;
-static gint disk_size = 0;
+static gint file_size = 0;
static gint peak_allocs = 0;
-static gint peak_disk_size = 0;
+static gint peak_file_size = 0;
void
gegl_tile_backend_file_stats (void)
{
g_warning ("leaked: %i chunks (%f mb) peak: %i (%i bytes %fmb))",
- allocs, disk_size / 1024 / 1024.0,
- peak_allocs, peak_disk_size, peak_disk_size / 1024 / 1024.0);
+ allocs, file_size / 1024 / 1024.0,
+ peak_allocs, peak_file_size, peak_file_size / 1024 / 1024.0);
}
static void
dbg_alloc (gint size)
{
allocs++;
- disk_size += size;
+ file_size += size;
if (allocs > peak_allocs)
peak_allocs = allocs;
- if (disk_size > peak_disk_size)
- peak_disk_size = disk_size;
+ if (file_size > peak_file_size)
+ peak_file_size = file_size;
}
static void
dbg_dealloc (gint size)
{
allocs--;
- disk_size -= size;
+ file_size -= size;
}
-static inline DiskEntry *
+static inline GeglBufferTile *
lookup_entry (GeglTileBackendFile *self,
gint x,
gint y,
gint z)
{
- DiskEntry key = { x, y, z, 0 };
-
- return g_hash_table_lookup (self->entries, &key);
+ GeglBufferTile *ret;
+ GeglBufferTile *key = gegl_tile_entry_new (x,y,z);
+ ret = g_hash_table_lookup (self->index, key);
+ gegl_tile_entry_destroy (key);
+ return ret;
}
/* this is the only place that actually should
@@ -233,14 +328,14 @@
gint z)
{
- GeglTileBackend *backend;
+ GeglTileBackend *backend;
GeglTileBackendFile *tile_backend_file;
- DiskEntry *entry;
- GeglTile *tile = NULL;
+ GeglBufferTile *entry;
+ GeglTile *tile = NULL;
- backend = GEGL_TILE_BACKEND (self);
+ backend = GEGL_TILE_BACKEND (self);
tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
- entry = lookup_entry (tile_backend_file, x, y, z);
+ entry = lookup_entry (tile_backend_file, x, y, z);
if (!entry)
return NULL;
@@ -249,7 +344,7 @@
tile->stored_rev = 1;
tile->rev = 1;
- disk_entry_read (tile_backend_file, entry, tile->data);
+ file_entry_read (tile_backend_file, entry, tile->data);
return tile;
}
@@ -260,28 +355,27 @@
gint y,
gint z)
{
- GeglTileBackend *backend;
+ GeglTileBackend *backend;
GeglTileBackendFile *tile_backend_file;
- DiskEntry *entry;
+ GeglBufferTile *entry;
- backend = GEGL_TILE_BACKEND (self);
+ backend = GEGL_TILE_BACKEND (self);
tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
- entry = lookup_entry (tile_backend_file, x, y, z);
-
+ entry = lookup_entry (tile_backend_file, x, y, z);
if (entry == NULL)
{
- entry = disk_entry_new (tile_backend_file);
+ entry = file_entry_new (tile_backend_file);
entry->x = x;
entry->y = y;
entry->z = z;
- g_hash_table_insert (tile_backend_file->entries, entry, entry);
+ g_hash_table_insert (tile_backend_file->index, entry, entry);
}
g_assert (tile->flags == 0); /* when this one is triggered, dirty pyramid data
has been tried written to persistent tile_storage.
*/
- disk_entry_write (tile_backend_file, entry, tile->data);
+ file_entry_write (tile_backend_file, entry, tile->data);
tile->stored_rev = tile->rev;
return NULL;
}
@@ -293,17 +387,17 @@
gint y,
gint z)
{
- GeglTileBackend *backend;
+ GeglTileBackend *backend;
GeglTileBackendFile *tile_backend_file;
- DiskEntry *entry;
+ GeglBufferTile *entry;
- backend = GEGL_TILE_BACKEND (self);
+ backend = GEGL_TILE_BACKEND (self);
tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
- entry = lookup_entry (tile_backend_file, x, y, z);
+ entry = lookup_entry (tile_backend_file, x, y, z);
if (entry != NULL)
{
- disk_entry_destroy (entry, tile_backend_file);
+ file_entry_destroy (entry, tile_backend_file);
}
return NULL;
@@ -318,7 +412,7 @@
{
GeglTileBackend *backend;
GeglTileBackendFile *tile_backend_file;
- DiskEntry *entry;
+ GeglBufferTile *entry;
backend = GEGL_TILE_BACKEND (self);
tile_backend_file = GEGL_TILE_BACKEND_FILE (backend);
@@ -327,6 +421,56 @@
return entry!=NULL?((gpointer)0x1):NULL;
}
+#include "gegl-buffer-index.h"
+
+static gpointer
+flush (GeglTileSource *source,
+ GeglTile *tile,
+ gint x,
+ gint y,
+ gint z)
+{
+ GeglTileBackend *backend;
+ GeglTileBackendFile *self;
+ GList *tiles;
+
+ backend = GEGL_TILE_BACKEND (source);
+ self = GEGL_TILE_BACKEND_FILE (backend);
+
+ g_print ("flushing %s\n", self->path);
+
+ gegl_buffer_header_init (&self->header,
+ backend->tile_width,
+ backend->tile_height,
+ backend->px_size,
+ backend->format
+ );
+ self->header.next = self->next_pre_alloc; /* this is the offset
+ we start handing
+ out headers from*/
+
+ tiles = g_hash_table_get_keys (self->index);
+
+ /* save the index */
+ {
+ GList *iter;
+ for (iter = tiles; iter; iter = iter->next)
+ {
+ GeglBufferItem *item = iter->data;
+
+ write_block (self, &item->block);
+ }
+ }
+ write_block (self, NULL); /* terminate the index */
+ g_output_stream_flush (self->o, NULL, NULL);
+ g_list_free (tiles);
+ write_header (self);
+
+ g_print ("flushed %s\n", self->path);
+
+ return (gpointer)0xf0f;
+}
+
enum
{
PROP_0,
@@ -349,13 +493,18 @@
return set_tile (self, data, x, y, z);
case GEGL_TILE_IDLE:
- return NULL;
+ return NULL; /* we could perhaps lazily be writing indexes
+ at some intervals, making it work as an
+ autosave for the buffer?
+ */
case GEGL_TILE_VOID:
return void_tile (self, data, x, y, z);
case GEGL_TILE_EXIST:
return exist_tile (self, data, x, y, z);
+ case GEGL_TILE_FLUSH:
+ return flush (self, data, x, y, z);
default:
g_assert (command < GEGL_TILE_LAST_COMMAND &&
@@ -411,18 +560,23 @@
{
GeglTileBackendFile *self = (GeglTileBackendFile *) object;
- g_hash_table_unref (self->entries);
-
- g_object_unref (self->i);
- g_object_unref (self->o);
+ if (self->index)
+ g_hash_table_unref (self->index);
+ if (self->i)
+ g_object_unref (self->i);
+ if (self->o)
+ g_object_unref (self->o);
/* check if we should nuke the buffer or not */
if(0)g_print ("finalizing buffer %s", self->path);
if (self->path)
- g_free (self->path);
+ g_free (self->path);
- g_file_delete (self->file, NULL, NULL);
- g_object_unref (self->file);
+ if (self->file)
+ {
+ g_file_delete (self->file, NULL, NULL);
+ g_object_unref (self->file);
+ }
(*G_OBJECT_CLASS (parent_class)->finalize)(object);
}
@@ -430,7 +584,7 @@
static guint
hashfunc (gconstpointer key)
{
- const DiskEntry *e = key;
+ const GeglBufferTile *e = key;
guint hash;
gint i;
gint srcA = e->x;
@@ -459,8 +613,8 @@
equalfunc (gconstpointer a,
gconstpointer b)
{
- const DiskEntry *ea = a;
- const DiskEntry *eb = b;
+ const GeglBufferTile *ea = a;
+ const GeglBufferTile *eb = b;
if (ea->x == eb->x &&
ea->y == eb->y &&
@@ -476,26 +630,32 @@
GObjectConstructParam *params)
{
GObject *object;
- GeglTileBackendFile *disk;
+ GeglTileBackendFile *self;
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
- disk = GEGL_TILE_BACKEND_FILE (object);
+ self = GEGL_TILE_BACKEND_FILE (object);
+
+ self->file = g_file_new_for_commandline_arg (self->path);
+ self->o = G_OUTPUT_STREAM (g_file_replace (self->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
+ g_output_stream_flush (self->o, NULL, NULL);
+ self->i = G_INPUT_STREAM (g_file_read (self->file, NULL, NULL));
+
+
+ self->next_pre_alloc = 256; /* reserved space for header */
+ self->total = 256; /* reserved space for header */
+ g_assert(g_seekable_seek (G_SEEKABLE (self->o), 256, G_SEEK_SET, NULL, NULL));
- disk->file = g_file_new_for_commandline_arg (disk->path);
- disk->o = G_OUTPUT_STREAM (g_file_replace (disk->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
- g_output_stream_flush (disk->o, NULL, NULL);
- disk->i = G_INPUT_STREAM (g_file_read (disk->file, NULL, NULL));
- if (!disk->file)
+ if (!self->file)
{
- g_warning ("Unable to open swap file '%s'\n",disk->path);
+ g_warning ("Unable to open swap file '%s'\n",self->path);
return NULL;
}
- g_assert (disk->file);
- g_assert (disk->i);
- g_assert (disk->o);
+ g_assert (self->file);
+ g_assert (self->i);
+ g_assert (self->o);
- disk->entries = g_hash_table_new (hashfunc, equalfunc);
+ self->index = g_hash_table_new (hashfunc, equalfunc);
return object;
}
@@ -528,12 +688,12 @@
static void
gegl_tile_backend_file_init (GeglTileBackendFile *self)
{
- self->path = NULL;
- self->file = NULL;
- self->i = NULL;
- self->o = NULL;
- self->entries = NULL;
- self->free_list = NULL;
- self->next_unused = 0;
- self->total = 0;
+ self->path = NULL;
+ self->file = NULL;
+ self->i = NULL;
+ self->o = NULL;
+ self->index = NULL;
+ self->free_list = NULL;
+ self->next_pre_alloc = 256; /* reserved space for header */
+ self->total = 256; /* reserved space for header */
}
Modified: trunk/gegl/buffer/gegl-tile-handler-cache.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile-handler-cache.c (original)
+++ trunk/gegl/buffer/gegl-tile-handler-cache.c Sun Apr 20 12:10:23 2008
@@ -192,7 +192,35 @@
{
case GEGL_TILE_SET:
/* nothing to do */
- break;
+ break; /* chain up */
+ case GEGL_TILE_FLUSH:
+ {
+ /*FIXME*/
+ /* do this for all tiles belonging to this cache */
+ gboolean exist = gegl_tile_handler_cache_has_tile (cache, x, y, z);
+ GeglTile *tile;
+ GList *link;
+
+ for (link = g_queue_peek_head_link (cache_queue); link; link = link->next)
+ {
+ CacheItem *item = link->data;
+ GeglTile *tile = item->tile;
+
+ if (tile != NULL &&
+ item->handler == cache)
+ {
+ gegl_tile_store (tile);
+ }
+ }
+
+ /*
+ if (exist)
+ {
+ tile = get_tile (tile_store, x, y, z);
+ gegl_tile_store (tile);
+ }*/
+ }
+ break; /* chain up */
case GEGL_TILE_GET:
/* XXX: we should perhaps store a NIL result, and place the empty
* generator after the cache, this would have to be possible to disable
Modified: trunk/gegl/buffer/gegl-tile-handler-log.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile-handler-log.c (original)
+++ trunk/gegl/buffer/gegl-tile-handler-log.c Sun Apr 20 12:10:23 2008
@@ -38,6 +38,7 @@
"void bl",
"void br",
"flush",
+ "invalidated",
"last command",
"eeek",
NULL
Modified: trunk/gegl/buffer/gegl-tile-source.h
==============================================================================
--- trunk/gegl/buffer/gegl-tile-source.h (original)
+++ trunk/gegl/buffer/gegl-tile-source.h Sun Apr 20 12:10:23 2008
@@ -48,6 +48,7 @@
GEGL_TILE_VOID_BL,
GEGL_TILE_VOID_BR,
GEGL_TILE_FLUSH,
+ GEGL_TILE_INVALIDATED,
GEGL_TILE_LAST_COMMAND
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]