[mapserver-commits] r12301 - in trunk/mapserver/mapcache: . include
src
svn at osgeo.org
svn at osgeo.org
Fri Aug 26 07:15:06 EDT 2011
Author: tbonfort
Date: 2011-08-26 04:15:06 -0700 (Fri, 26 Aug 2011)
New Revision: 12301
Added:
trunk/mapserver/mapcache/src/cache_memcache.c
Modified:
trunk/mapserver/mapcache/Makefile.inc.in
trunk/mapserver/mapcache/configure.in
trunk/mapserver/mapcache/geocache.xml
trunk/mapserver/mapcache/include/geocache.h
trunk/mapserver/mapcache/src/configuration.c
Log:
s/wms/wmts/ in error messages
thomas.bonfort | 2011-02-08 18:42:42 +0100 (Tue, 08 Feb 2011)
Modified: trunk/mapserver/mapcache/Makefile.inc.in
===================================================================
--- trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:14:59 UTC (rev 12300)
+++ trunk/mapserver/mapcache/Makefile.inc.in 2011-08-26 11:15:06 UTC (rev 12301)
@@ -12,6 +12,10 @@
CURL_CFLAGS=@CURL_CFLAGS@
CURL_LIBS=@CURL_LIBS@
+APU_INC=@APU_INC@
+APU_LIBS=@APU_LIBS@
+MEMCACHE_ENABLED=@MEMCACHE_ENABLED@
+
APR_INC=@APR_INC@
APR_LIBS=@APR_LIBS@
@@ -34,8 +38,8 @@
GDAL_LIB=@GDAL_LIB@
GDAL_ENABLED=@GDAL_ENABLED@
-INCLUDES=-I../include $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GDAL_ENABLED) $(APR_INC) $(PCRE_CFLAGS) $(PCRE_ENABLED)
-LIBS=$(CURL_LIBS) $(PNG_LIB) $(JPEG_LIB) $(GDAL_LIB) $(APR_LIBS) $(PCRE_LIBS)
+INCLUDES=-I../include $(CURL_CFLAGS) $(PNG_INC) $(JPEG_INC) $(GDAL_INC) $(GDAL_ENABLED) $(APR_INC) $(APU_INC) $(MEMCACHE_ENABLED) $(PCRE_CFLAGS) $(PCRE_ENABLED)
+LIBS=$(CURL_LIBS) $(PNG_LIB) $(JPEG_LIB) $(GDAL_LIB) $(APR_LIBS) $(APU_LIBS) $(PCRE_LIBS)
Modified: trunk/mapserver/mapcache/configure.in
===================================================================
--- trunk/mapserver/mapcache/configure.in 2011-08-26 11:14:59 UTC (rev 12300)
+++ trunk/mapserver/mapcache/configure.in 2011-08-26 11:15:06 UTC (rev 12301)
@@ -109,6 +109,71 @@
AC_SUBST(CURL_LIBS,`$CURLCONFIG --libs`)
])
+AC_DEFUN([APU_CHECK],[
+ AC_SUBST(APUCONFIG)
+ AC_SUBST(MEMCACHE_ENABLED)
+ AC_ARG_WITH(apu_config,
+ AC_HELP_STRING([--with-apu-config], [path to apu-config program]),
+ ,
+ [with_apu_config=yes]
+ )
+ if test "$with_apu_config" = "yes"; then
+ AC_MSG_CHECKING(for apu-config in default locations)
+ if test -n "$APXS"; then
+ APXSFULL=`which "$APXS"`
+ APXSDIR=`dirname "$APXSFULL"`
+ if test -x "$APXSDIR/apu-config"; then
+ APUCONFIG="$APXSDIR/apu-config"
+ elif test -x "$APXSDIR/apu-1-config"; then
+ APUCONFIG="$APXSDIR/apu-1-config"
+ fi
+ fi
+ if test -z "$APUCONFIG"; then
+ AC_PATH_PROG(APUCONFIG, apu-config)
+ fi
+ if test -z "$APUCONFIG"; then
+ AC_PATH_PROG(APUCONFIG, apu-1-config)
+ fi
+ if test -n "$APUCONFIG"; then
+ AC_MSG_RESULT([using $APUCONFIG, use --with-apu-config=/path/to/apu-(1-)config to modify])
+ else
+ AC_MSG_RESULT([not found])
+ fi
+ else
+ AC_MSG_CHECKING(for apu-config usability in $with_apu_config)
+ if test -x "$with_apu_config"; then
+ APUCONFIG=$with_apu_config
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_ERROR($with_apu_config not found or not executable)
+ fi
+ fi
+ if test -z "$APUCONFIG"; then
+ AC_MSG_ERROR(apu-config utility not found. memcache backend will be disabled)
+ else
+ OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS `$APUCONFIG --ldflags --libs --link-ld`"
+ OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS `$APUCONFIG --includes`"
+ AC_CHECK_LIB(aprutil-1, apr_memcache_hash,[APU_LIBS=`$APUCONFIG --link-libtool`],)
+ if test -z "$APU_LIBS"; then
+ AC_CHECK_LIB(aprutil, apr_memcache_hash,[APU_LIBS=`$APUCONFIG --link-libtool`],
+ [AC_MSG_WARN([unable to link to apr-util, memcache cache backend disabled])])
+ fi
+ if test -n "$APU_LIBS"; then
+ AC_CHECK_HEADER([apr_memcache.h],[
+ MEMCACHE_ENABLED=[-DUSE_MEMCACHE]
+ APU_INC=`$APUCONFIG --includes`
+ ],
+ [AC_MSG_WARN([apr_memcache.h not found, memcache cache backend disabled])])
+ fi
+ CPPFLAGS="$OLDCPPFLAGS"
+ LDFLAGS="$OLDLDFLAGS"
+ fi
+ AC_SUBST(APUCONFIG)
+ AC_SUBST(MEMCACHE_ENABLED)
+ AC_SUBST(APU_INC)
+ AC_SUBST(APU_LIBS)
+])
+
AC_DEFUN([APR_CHECK],[
AC_SUBST(APRCONFIG)
AC_ARG_WITH(apr_config,
@@ -446,6 +511,7 @@
fi
APR_CHECK
+APU_CHECK
PNG_CHECK
Modified: trunk/mapserver/mapcache/geocache.xml
===================================================================
--- trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:14:59 UTC (rev 12300)
+++ trunk/mapserver/mapcache/geocache.xml 2011-08-26 11:15:06 UTC (rev 12301)
@@ -171,6 +171,18 @@
<symlink_blank/>
</cache>
+ <!-- memcache cache
+ entry accepts multiple <server> entries
+ -->
+ <!--
+ <cache name="memcache" type="memcache">
+ <server>
+ <host>localhost</host>
+ <port>11211</port>
+ </server>
+ </cache>
+ -->
+
<!-- format
a format is an image algorithm used for compressing images
Modified: trunk/mapserver/mapcache/include/geocache.h
===================================================================
--- trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:14:59 UTC (rev 12300)
+++ trunk/mapserver/mapcache/include/geocache.h 2011-08-26 11:15:06 UTC (rev 12301)
@@ -41,6 +41,10 @@
#include <regex.h>
#endif
+#ifdef USE_MEMCACHE
+#include <apr_memcache.h>
+#endif
+
#define GEOCACHE_SUCCESS 0
#define GEOCACHE_FAILURE 1
#define GEOCACHE_TRUE 1
@@ -267,6 +271,9 @@
/** @{ */
typedef enum {
GEOCACHE_CACHE_DISK
+#ifdef USE_MEMCACHE
+ ,GEOCACHE_CACHE_MEMCACHE
+#endif
} geocache_cache_type;
/** \interface geocache_cache
@@ -308,6 +315,25 @@
int symlink_blank;
};
+#ifdef USE_MEMCACHE
+
+typedef struct geocache_cache_memcache geocache_cache_memcache;
+/**\class geocache_cache_memcache
+ * \brief a geocache_cache on memcached servers
+ * \implements geocache_cache
+ */
+struct geocache_cache_memcache {
+ geocache_cache cache;
+ apr_memcache_t *memcache;
+};
+
+/**
+ * \memberof geocache_cache_memcache
+ */
+geocache_cache* geocache_cache_memcache_create(geocache_context *ctx);
+
+#endif
+
/** @} */
Added: trunk/mapserver/mapcache/src/cache_memcache.c
===================================================================
--- trunk/mapserver/mapcache/src/cache_memcache.c (rev 0)
+++ trunk/mapserver/mapcache/src/cache_memcache.c 2011-08-26 11:15:06 UTC (rev 12301)
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2010 Thomas Bonfort
+ *
+ * Licensed 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.
+ */
+
+#ifdef USE_MEMCACHE
+
+#include "geocache.h"
+
+
+
+/**
+ * \brief return key for given tile
+ *
+ * \param tile the tile to get the key from
+ * \param key pointer to a char* that will contain the key
+ * \param ctx
+ * \private \memberof geocache_cache_memcache
+ */
+static void _geocache_cache_memcache_tile_key(geocache_context *ctx, geocache_tile *tile, char **path) {
+ char *start;
+ start = apr_pstrcat(ctx->pool,
+ tile->tileset->name,"/",
+ tile->grid_link->grid->name,
+ NULL);
+ if(tile->dimensions) {
+ const apr_array_header_t *elts = apr_table_elts(tile->dimensions);
+ int i = elts->nelts;
+ while(i--) {
+ apr_table_entry_t *entry = &(APR_ARRAY_IDX(elts,i,apr_table_entry_t));
+ start = apr_pstrcat(ctx->pool,start,"/",entry->key,"/",entry->val,NULL);
+ }
+ }
+ *path = apr_psprintf(ctx->pool,"%s/%02d/%03d/%03d/%03d/%03d/%03d/%03d.%s",
+ start,
+ tile->z,
+ tile->x / 1000000,
+ (tile->x / 1000) % 1000,
+ tile->x % 1000,
+ tile->y / 1000000,
+ (tile->y / 1000) % 1000,
+ tile->y % 1000,
+ tile->tileset->format?tile->tileset->format->extension:"png");
+ if(!*path) {
+ ctx->set_error(ctx,500, "failed to allocate tile key");
+ }
+
+}
+
+static int _geocache_cache_memcache_has_tile(geocache_context *ctx, geocache_tile *tile) {
+ char *key, *tmpdata;
+ int rv;
+ size_t tmpdatasize;
+ geocache_cache_memcache *cache = (geocache_cache_memcache*)tile->tileset->cache;
+ _geocache_cache_memcache_tile_key(ctx, tile, &key);
+ if(GC_HAS_ERROR(ctx)) {
+ return GEOCACHE_FALSE;
+ }
+ rv = apr_memcache_getp(cache->memcache,ctx->pool,key,&tmpdata,&tmpdatasize,NULL);
+ if(rv != APR_SUCCESS) {
+ return GEOCACHE_FALSE;
+ }
+ if(tmpdatasize == 0) {
+ return GEOCACHE_FALSE;
+ }
+ return GEOCACHE_TRUE;
+}
+
+
+/**
+ * \brief get content of given tile
+ *
+ * fills the geocache_tile::data of the given tile with content stored on the memcache server
+ * \private \memberof geocache_cache_memcache
+ * \sa geocache_cache::tile_get()
+ */
+static int _geocache_cache_memcache_get(geocache_context *ctx, geocache_tile *tile) {
+ char *key;
+ int rv;
+ geocache_cache_memcache *cache = (geocache_cache_memcache*)tile->tileset->cache;
+ _geocache_cache_memcache_tile_key(ctx, tile, &key);
+ if(GC_HAS_ERROR(ctx)) {
+ return GEOCACHE_FAILURE;
+ }
+ tile->data = geocache_buffer_create(0,ctx->pool);
+ rv = apr_memcache_getp(cache->memcache,ctx->pool,key,(char**)&tile->data->buf,&tile->data->size,NULL);
+ if(rv != APR_SUCCESS) {
+ return GEOCACHE_CACHE_MISS;
+ }
+ if(tile->data->size == 0) {
+ ctx->set_error(ctx,500,"memcache cache returned 0-length data for tile %d %d %d\n",tile->x,tile->y,tile->z);
+ return GEOCACHE_FAILURE;
+ }
+ tile->data->avail = tile->data->size;
+ return GEOCACHE_SUCCESS;
+}
+
+/**
+ * \brief push tile data to memcached
+ *
+ * writes the content of geocache_tile::data to the configured memcached instance(s)
+ * \returns GEOCACHE_FAILURE if there is no data to write, or if the tile isn't locked
+ * \returns GEOCACHE_SUCCESS if the tile has been successfully written
+ * \private \memberof geocache_cache_memcache
+ * \sa geocache_cache::tile_set()
+ */
+static void _geocache_cache_memcache_set(geocache_context *ctx, geocache_tile *tile) {
+ char *key;
+ int rv;
+ int expires = tile->tileset->expires?tile->tileset->expires:3600;
+ geocache_cache_memcache *cache = (geocache_cache_memcache*)tile->tileset->cache;
+ _geocache_cache_memcache_tile_key(ctx, tile, &key);
+ GC_CHECK_ERROR(ctx);
+
+ rv = apr_memcache_set(cache->memcache,key,(char*)tile->data->buf,tile->data->size,expires,0);
+ if(rv != APR_SUCCESS) {
+ ctx->set_error(ctx,500,"failed to store tile %d %d %d to memcache cache %s",
+ tile->x,tile->y,tile->z,cache->cache.name);
+ return;
+ }
+}
+
+/**
+ * \private \memberof geocache_cache_memcache
+ */
+static void _geocache_cache_memcache_configuration_parse(geocache_context *ctx, ezxml_t node, geocache_cache *cache) {
+ ezxml_t cur_node;
+ geocache_cache_memcache *dcache = (geocache_cache_memcache*)cache;
+ int servercount = 0;
+ for(cur_node = ezxml_child(node,"server"); cur_node; cur_node = cur_node->next) {
+ servercount++;
+ }
+ if(!servercount) {
+ ctx->set_error(ctx,400,"memcache cache %s has no <server>s configured",cache->name);
+ return;
+ }
+ if(APR_SUCCESS != apr_memcache_create(ctx->pool, servercount, 0, &dcache->memcache)) {
+ ctx->set_error(ctx,400,"cache %s: failed to create memcache backend", cache->name);
+ return;
+ }
+ for(cur_node = ezxml_child(node,"server"); cur_node; cur_node = cur_node->next) {
+ ezxml_t xhost = ezxml_child(cur_node,"host");
+ ezxml_t xport = ezxml_child(cur_node,"port");
+ const char *host;
+ apr_memcache_server_t *server;
+ apr_port_t port;
+ if(!xhost || !xhost->txt || ! *xhost->txt) {
+ ctx->set_error(ctx,400,"cache %s: <server> with no <host>",cache->name);
+ return;
+ } else {
+ host = apr_pstrdup(ctx->pool,xhost->txt);
+ }
+
+ if(!xport || !xport->txt || ! *xport->txt) {
+ ctx->set_error(ctx,400,"cache %s: <server> with no <port>", cache->name);
+ return;
+ } else {
+ char *endptr;
+ int iport = (int)strtol(xport->txt,&endptr,10);
+ if(*endptr != 0) {
+ ctx->set_error(ctx,400,"failed to parse value %s for memcache cache %s", xport->txt,cache->name);
+ return;
+ }
+ port = iport;
+ }
+ if(APR_SUCCESS != apr_memcache_server_create(ctx->pool,host,port,4,5,50,10,&server)) {
+ ctx->set_error(ctx,400,"cache %s: failed to create server %s:%d",cache->name,host,port);
+ return;
+ }
+ if(APR_SUCCESS != apr_memcache_add_server(dcache->memcache,server)) {
+ ctx->set_error(ctx,400,"cache %s: failed to add server %s:%d",cache->name,host,port);
+ return;
+ }
+ if(APR_SUCCESS != apr_memcache_set(dcache->memcache,"geocache_test_key","geocache",8,0,0)) {
+ ctx->set_error(ctx,400,"cache %s: failed to add test key to server %s:%d",cache->name,host,port);
+ return;
+ }
+ }
+}
+
+/**
+ * \private \memberof geocache_cache_memcache
+ */
+static void _geocache_cache_memcache_configuration_check(geocache_context *ctx, geocache_cache *cache) {
+ geocache_cache_memcache *dcache = (geocache_cache_memcache*)cache;
+ if(!dcache->memcache || dcache->memcache->ntotal==0) {
+ ctx->set_error(ctx,400,"cache %s has no servers configured");
+ }
+}
+
+
+/**
+ * \brief creates and initializes a geocache_memcache_cache
+ */
+geocache_cache* geocache_cache_memcache_create(geocache_context *ctx) {
+ geocache_cache_memcache *cache = apr_pcalloc(ctx->pool,sizeof(geocache_cache_memcache));
+ if(!cache) {
+ ctx->set_error(ctx, 500, "failed to allocate memcache cache");
+ return NULL;
+ }
+ cache->cache.metadata = apr_table_make(ctx->pool,3);
+ cache->cache.type = GEOCACHE_CACHE_MEMCACHE;
+ cache->cache.tile_get = _geocache_cache_memcache_get;
+ cache->cache.tile_exists = _geocache_cache_memcache_has_tile;
+ cache->cache.tile_set = _geocache_cache_memcache_set;
+ cache->cache.configuration_check = _geocache_cache_memcache_configuration_check;
+ cache->cache.configuration_parse = _geocache_cache_memcache_configuration_parse;
+ return (geocache_cache*)cache;
+}
+
+#endif
+
+/* vim: ai ts=3 sts=3 et sw=3
+*/
Modified: trunk/mapserver/mapcache/src/configuration.c
===================================================================
--- trunk/mapserver/mapcache/src/configuration.c 2011-08-26 11:14:59 UTC (rev 12300)
+++ trunk/mapserver/mapcache/src/configuration.c 2011-08-26 11:15:06 UTC (rev 12301)
@@ -537,6 +537,13 @@
}
if(!strcmp(type,"disk")) {
cache = geocache_cache_disk_create(ctx);
+ } else if(!strcmp(type,"memcache")) {
+#ifdef USE_MEMCACHE
+ cache = geocache_cache_memcache_create(ctx);
+#else
+ ctx->set_error(ctx,400, "failed to add cache %s: memcache support is not available on this build",name);
+ return;
+#endif
} else {
ctx->set_error(ctx, 400, "unknown cache type %s for cache \"%s\"", type, name);
return;
More information about the mapserver-commits
mailing list