From 116c89bf209fcf57c6ab5a693763c7bf48fb8bd7 Mon Sep 17 00:00:00 2001 From: gnuite Date: Mon, 9 Mar 2009 02:23:10 +0000 Subject: [PATCH] Removed the heinous embedding of timestamps into PNGs. Layer refreshing is now done on an interval fixed across the entire layer. git-svn-id: svn+ssh://garage/var/lib/gforge/svnroot/maemo-mapper/trunk@246 6c538b50-5814-0410-93ad-8bdf4c0149d1 --- src/display.c | 40 ++++------ src/main.c | 32 +------- src/maps.c | 202 ++++++++++++++++++++++++++++++++++++++----------- src/maps.h | 5 +- src/settings.c | 28 ------- 5 files changed, 176 insertions(+), 131 deletions(-) diff --git a/src/display.c b/src/display.c index 67ee632..57159d5 100644 --- a/src/display.c +++ b/src/display.c @@ -1822,6 +1822,7 @@ combine_tiles (GdkPixbuf *dst_pixbuf, GdkPixbuf *src_pixbuf) gint bps = gdk_pixbuf_get_bits_per_sample (dst_pixbuf); gint width, height, x, y, d_delta, s_delta; guchar *d_p, *s_p; + printf("combine_tiles()\n"); if (gdk_pixbuf_get_colorspace (dst_pixbuf) != gdk_pixbuf_get_colorspace (src_pixbuf)) { printf ("combine return (1)\n"); @@ -2029,35 +2030,22 @@ thread_render_map(MapRenderTask *mrt) tilex >> zoff, tiley >> zoff))) { - /* Found a map. Check for it's age. */ - gint age = get_tile_age (layer_pixbuf); - printf ("Tile age (%d)\n", age); - - /* throw away tile only if we can download something */ - if (!repo_p->layer_refresh_interval || - age < repo_p->layer_refresh_interval * 60 || - !_auto_download) + /* if this is a layer's tile, join with main tile */ + if (repo_p != mrt->repo) { - /* if this is a layer's tile, join with main tile */ - if (repo_p != mrt->repo) - { - /* but only if main layer is exists */ - if (tile_pixbuf) - combine_tiles (tile_pixbuf, layer_pixbuf); - g_object_unref (layer_pixbuf); - } - else { - tile_pixbuf = layer_pixbuf; - zoff_base = zoff; - } - break; - } - else + /* but only if main layer is exists */ + if (tile_pixbuf) + combine_tiles (tile_pixbuf, layer_pixbuf); g_object_unref (layer_pixbuf); + } + else { + tile_pixbuf = layer_pixbuf; + zoff_base = zoff; + } + break; } - else - if (repo_p->layers) - _refresh_map_after_download = TRUE; + else if (repo_p->layers) + _refresh_map_after_download = TRUE; } /* Else we're not going to be drawing this map, so just check * if it's in the database. */ diff --git a/src/main.c b/src/main.c index 8c2b2bc..b0fdb26 100644 --- a/src/main.c +++ b/src/main.c @@ -202,34 +202,7 @@ maemo_mapper_destroy() #endif g_thread_pool_free(_mut_thread_pool, TRUE, TRUE); - if(MAPDB_EXISTS(_curr_repo)) - { - RepoData* repo_p; - if(_curr_repo->is_sqlite) - { - g_mutex_lock(_mapdb_mutex); - sqlite3_close(_curr_repo->sqlite_db); - _curr_repo->sqlite_db = NULL; - g_mutex_unlock(_mapdb_mutex); - } - else - { - g_mutex_lock(_mapdb_mutex); - repo_p = _curr_repo; - while (repo_p) { - if (repo_p->gdbm_db) { -/* /\* perform reorganization for layers which are auto refreshed *\/ */ -/* if (repo_p->layer_level && repo_p->layer_refresh_interval) */ -/* gdbm_reorganize (repo_p->gdbm_db); */ - gdbm_close(repo_p->gdbm_db); - } - repo_p->gdbm_db = NULL; - repo_p = repo_p->layers; - } - g_mutex_unlock(_mapdb_mutex); - } - } - map_cache_destroy(); + maps_destroy(); gps_destroy(TRUE); @@ -466,7 +439,8 @@ maemo_mapper_init(gint argc, gchar **argv) #endif settings_init(); - map_cache_init(_map_cache_size); + + maps_init(_map_cache_size); /* Initialize _program. */ _program = HILDON_PROGRAM(hildon_program_get_instance()); diff --git a/src/maps.c b/src/maps.c index 4d4e638..48e5a0b 100644 --- a/src/maps.c +++ b/src/maps.c @@ -520,7 +520,7 @@ map_cache_init_unlocked(size_t cache_size) map_cache_evict(0); } -void +static void map_cache_init(size_t cache_size) { g_mutex_lock(_mapdb_mutex); @@ -557,7 +557,8 @@ map_cache_destroy_unlocked(void) _map_cache.thits+_map_cache.bhits+_map_cache.misses)); } } -void + +static void map_cache_destroy(void) { g_mutex_lock(_mapdb_mutex); @@ -565,18 +566,47 @@ map_cache_destroy(void) g_mutex_unlock(_mapdb_mutex); } +static void +clean_layers_from_cache(MapCacheKey *key, MapCacheEntry *value, RepoData *repo) +{ + if(key->repo == repo) + map_cache_entry_free_pixbuf(value); +} void map_cache_clean (void) { g_mutex_lock(_mapdb_mutex); - gint old_size = _map_cache.cache_size; - map_cache_destroy_unlocked(); - map_cache_init_unlocked(old_size); + g_hash_table_foreach(_map_cache.entries, + (GHFunc)clean_layers_from_cache, _curr_repo); g_mutex_unlock(_mapdb_mutex); } +static gboolean +remove_repo_from_cache(MapCacheKey *key, MapCacheEntry *value, RepoData *repo) +{ + if (key->repo == repo) + printf("REMOVING ENTRY AT (%d, %d, %d)\n", + key->zoom, key->tilex, key->tiley); + return key->repo == repo; +} + +/** + * This method "refreshes" a layer by both removing the layer from the cache + * and removing the layer-applied pixbufs from the base repo's cache entries. + */ +static void +map_cache_clean_layer(RepoData *layer) +{ + printf("%s()\n", __PRETTY_FUNCTION__); + + g_hash_table_foreach_remove(_map_cache.entries, + (GHRFunc)remove_repo_from_cache, layer); + + vprintf("%s(): return\n", __PRETTY_FUNCTION__); +} + gboolean mapdb_exists(RepoData *repo, gint zoom, gint tilex, gint tiley) { @@ -691,7 +721,7 @@ mapdb_update(RepoData *repo, gint zoom, gint tilex, gint tiley, || SQLITE_DONE != sqlite3_step(repo->stmt_map_update)) { success = FALSE; - printf("Error in mapdb_update: %s\n", + fprintf(stderr, "Error in mapdb_update: %s\n", sqlite3_errmsg(repo->sqlite_db)); } sqlite3_reset(repo->stmt_map_update); @@ -1375,24 +1405,6 @@ thread_proc_mut() } g_object_unref(loader); - /* attach timestamp with loaded pixbuf */ - { - gchar* new_bytes; - gsize new_size; - GError* error = NULL; - char ts_val[12]; - - sprintf (ts_val, "%u", (unsigned int)time (NULL)); - - /* update bytes with new, timestamped pixbuf */ - if (gdk_pixbuf_save_to_buffer (mut->pixbuf, &new_bytes, &new_size, "png", &error, layer_timestamp_key, ts_val, NULL)) - { - g_free (bytes); - bytes = new_bytes; - size = new_size; - } - } - /* Copy database-relevant mut data before we release it. */ repo = mut->repo; zoom = mut->zoom; @@ -1576,7 +1588,7 @@ thread_repoman_compact(CompactInfo *ci) ci->status_msg = _("Failed to open map database for compacting."); else { - if(SQLITE_OK != sqlite3_exec(db, "VACUUM;", NULL, NULL, NULL)) + if(SQLITE_OK != sqlite3_exec(db, "vacuum;", NULL, NULL, NULL)) ci->status_msg = _("An error occurred while trying to " "compact the database."); else @@ -2630,6 +2642,7 @@ repoman_layers(GtkWidget *widget, RepoManInfo *rmi) *rdp = rd; rd->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (lei->txt_name))); + rd->is_sqlite = rei->repo->is_sqlite; rd->url = g_strdup (gtk_entry_get_text (GTK_ENTRY (lei->txt_url))); rd->db_filename = g_strdup (gtk_entry_get_text (GTK_ENTRY (lei->txt_db))); rd->layer_enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lei->chk_visible)); @@ -3734,8 +3747,6 @@ void maps_toggle_visible_layers () vprintf("%s(): return\n", __PRETTY_FUNCTION__); } - - /* this routine fired by timer every minute and decrements refetch counter of every active layer of current repository. If one of layer is expired, it forces map redraw. Redraw routine checks every layer's tile download timestamp and desides performs refetch if needed */ @@ -3747,46 +3758,145 @@ map_layer_refresh_cb (gpointer data) printf("%s()\n", __PRETTY_FUNCTION__); if (rd) { - rd = rd->layers; - - while (rd) { + for(rd = rd->layers; rd; rd = rd->layers) + { if (rd->layer_enabled && rd->layer_refresh_interval) { rd->layer_refresh_countdown--; if (rd->layer_refresh_countdown <= 0) { rd->layer_refresh_countdown = rd->layer_refresh_interval; refresh = TRUE; + + printf("Refreshing layer: %s\n", rd->name); + g_mutex_lock(_mapdb_mutex); + if(MAPDB_EXISTS(rd)) + { + /* Clear the database. */ + if(rd->is_sqlite) + sqlite3_exec(rd->sqlite_db, "delete from maps;", + NULL, NULL, NULL); + else + { + gdbm_close(rd->gdbm_db); + g_remove(rd->db_filename); + rd->gdbm_db = gdbm_open(rd->db_filename, + 0, GDBM_WRCREAT | GDBM_FAST, 0644, NULL); + } + } + map_cache_clean_layer(rd); + g_mutex_unlock(_mapdb_mutex); } } - - rd = rd->layers; } } if (refresh) + { + map_cache_clean(); map_refresh_mark (TRUE); + } vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__); return TRUE; } +void +maps_init(gint map_cache_size) +{ + printf("%s()\n", __PRETTY_FUNCTION__); + map_cache_init(map_cache_size); -/* - Returns amount of seconds since tile downloaded or 0 if tile - have no such information. -*/ -gint get_tile_age (GdkPixbuf* pixbuf) + if(_repo_list == NULL) + { + /* We have no repositories - create a default one. */ + RepoData *repo = g_new0(RepoData, 1); + + repo->db_filename = gnome_vfs_expand_initial_tilde( + REPO_DEFAULT_CACHE_DIR); + repo->url=g_strdup(REPO_DEFAULT_MAP_URI); + repo->dl_zoom_steps = REPO_DEFAULT_DL_ZOOM_STEPS; + repo->name = g_strdup(REPO_DEFAULT_NAME); + repo->view_zoom_steps = REPO_DEFAULT_VIEW_ZOOM_STEPS; + repo->double_size = FALSE; + repo->nextable = TRUE; + repo->min_zoom = REPO_DEFAULT_MIN_ZOOM; + repo->max_zoom = REPO_DEFAULT_MAX_ZOOM; + repo->layers = NULL; + repo->layer_level = 0; + repo->is_sqlite = TRUE; + set_repo_type(repo); + + _repo_list = g_list_append(_repo_list, repo); + repo_set_curr(repo); + } + + /* this timer decrements layers' counters, clears layer databases, and + * frefresh map if needed */ + g_timeout_add (60 * 1000, map_layer_refresh_cb, NULL); + + vprintf("%s(): return\n", __PRETTY_FUNCTION__); +} + +void +maps_destroy() { - const char* ts; - guint val; + GList *curr; + printf("%s()\n", __PRETTY_FUNCTION__); - ts = gdk_pixbuf_get_option (pixbuf, layer_timestamp_key); + map_cache_destroy(); - if (!ts) - return 0; + g_mutex_lock(_mapdb_mutex); - if (sscanf (ts, "%u", &val)) - return time (NULL) - val; - else - return 0; + if(MAPDB_EXISTS(_curr_repo)) + { + RepoData* repo_p; + for(repo_p = _curr_repo; repo_p; repo_p = repo_p->layers) + { + if(repo_p->is_sqlite) + { + if(repo_p->sqlite_db) + { + sqlite3_close(repo_p->sqlite_db); + repo_p->sqlite_db = NULL; + } + } + else + { + if (repo_p->gdbm_db) { + gdbm_close(repo_p->gdbm_db); + repo_p->gdbm_db = NULL; + } + } + } + } + + /* Go through layer repos and empty ephemeral ones. */ + for(curr = _repo_list; curr; curr = curr->next) + { + RepoData *repo; + for(repo = ((RepoData*)curr->data)->layers; repo; repo = repo->layers) + { + if(repo->layer_refresh_interval != 0) + { + printf("Clearing database: %s\n", repo->name); + if(repo->is_sqlite) + { + sqlite3 *db; + if(SQLITE_OK == sqlite3_open(repo->db_filename, &db)) + sqlite3_exec(db, "delete from maps;", NULL, NULL, NULL); + sqlite3_exec(db, "vacuum;", NULL, NULL, NULL); + } + else + { + /* Just delete the file and re-create. */ + g_remove(repo->db_filename); + close(g_creat(repo->db_filename, 0644)); + } + } + } + } + + g_mutex_unlock(_mapdb_mutex); + + vprintf("%s(): return\n", __PRETTY_FUNCTION__); } diff --git a/src/maps.h b/src/maps.h index 50087eb..5af0103 100644 --- a/src/maps.h +++ b/src/maps.h @@ -24,11 +24,12 @@ #ifndef MAEMO_MAPPER_MAPS_H #define MAEMO_MAPPER_MAPS_H -void map_cache_init(size_t cache_size); size_t map_cache_resize(size_t cache_size); -void map_cache_destroy(void); void map_cache_clean (void); +void maps_init(); +void maps_destroy(); + gboolean mapdb_exists(RepoData *repo, gint zoom, gint tilex, gint tiley); GdkPixbuf* mapdb_get(RepoData *repo, gint zoom, gint tilex, gint tiley); diff --git a/src/settings.c b/src/settings.c index 93540fd..11a2346 100644 --- a/src/settings.c +++ b/src/settings.c @@ -2609,34 +2609,6 @@ settings_init() if (curr_repo) repo_set_curr(curr_repo); - - /* this timer decrements layers' counters and frefresh map if needed */ - g_timeout_add (60 * 1000, map_layer_refresh_cb, NULL); - } - - - if(_repo_list == NULL) - { - /* We have no repositories - create a default one. */ - RepoData *repo = g_new0(RepoData, 1); - - repo->db_filename = gnome_vfs_expand_initial_tilde( - REPO_DEFAULT_CACHE_DIR); - repo->url=g_strdup(REPO_DEFAULT_MAP_URI); - repo->dl_zoom_steps = REPO_DEFAULT_DL_ZOOM_STEPS; - repo->name = g_strdup(REPO_DEFAULT_NAME); - repo->view_zoom_steps = REPO_DEFAULT_VIEW_ZOOM_STEPS; - repo->double_size = FALSE; - repo->nextable = TRUE; - repo->min_zoom = REPO_DEFAULT_MIN_ZOOM; - repo->max_zoom = REPO_DEFAULT_MAX_ZOOM; - repo->layers = NULL; - repo->layer_level = 0; - repo->is_sqlite = TRUE; - set_repo_type(repo); - - _repo_list = g_list_append(_repo_list, repo); - repo_set_curr(repo); } /* Get last Zoom Level. Default is 16. */ -- 2.45.0