static svn_error_t * test_memcache_basic(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_cache__t *cache; svn_config_t *config; svn_memcache_t *memcache = NULL; const char *prefix = apr_psprintf(pool, "test_memcache_basic-%" APR_TIME_T_FMT, apr_time_now()); if (opts->config_file) { SVN_ERR(svn_config_read2(&config, opts->config_file, TRUE, FALSE, pool)); SVN_ERR(svn_cache__make_memcache_from_config(&memcache, config, pool)); } if (! memcache) return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, "not configured to use memcached"); /* Create a memcache-based cache. */ SVN_ERR(svn_cache__create_memcache(&cache, memcache, serialize_revnum, deserialize_revnum, APR_HASH_KEY_STRING, prefix, pool)); return basic_cache_test(cache, FALSE, pool); }
static svn_error_t * test_memcache_long_key(const svn_test_opts_t *opts, apr_pool_t *pool) { svn_cache__t *cache; svn_config_t *config; svn_memcache_t *memcache = NULL; svn_revnum_t fifty = 50, *answer; svn_boolean_t found = FALSE; const char *prefix = apr_psprintf(pool, "test_memcache_long_key-%" APR_TIME_T_FMT, apr_time_now()); static const char *long_key = "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 50 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 100 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 150 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 200 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 250 */ "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 300 */ ; if (opts->config_file) { SVN_ERR(svn_config_read3(&config, opts->config_file, TRUE, FALSE, FALSE, pool)); SVN_ERR(svn_cache__make_memcache_from_config(&memcache, config, pool, pool)); } if (! memcache) return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, "not configured to use memcached"); /* Create a memcache-based cache. */ SVN_ERR(svn_cache__create_memcache(&cache, memcache, serialize_revnum, deserialize_revnum, APR_HASH_KEY_STRING, prefix, pool)); SVN_ERR(svn_cache__set(cache, long_key, &fifty, pool)); SVN_ERR(svn_cache__get((void **) &answer, &found, cache, long_key, pool)); if (! found) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "cache failed to find entry for 'fifty'"); if (*answer != 50) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "expected 50 but found '%ld'", *answer); return SVN_NO_ERROR; }
svn_error_t * svn_fs_fs__initialize_caches(svn_fs_t *fs, apr_pool_t *pool) { fs_fs_data_t *ffd = fs->fsap_data; const char *prefix = apr_pstrcat(pool, "fsfs:", ffd->uuid, "/", fs->path, ":", NULL); svn_memcache_t *memcache; svn_boolean_t no_handler; SVN_ERR(read_config(&memcache, &no_handler, fs, pool)); /* Make the cache for revision roots. For the vast majority of * commands, this is only going to contain a few entries (svnadmin * dump/verify is an exception here), so to reduce overhead let's * try to keep it to just one page. I estimate each entry has about * 72 bytes of overhead (svn_revnum_t key, svn_fs_id_t + * id_private_t + 3 strings for value, and the cache_entry); the * default pool size is 8192, so about a hundred should fit * comfortably. */ if (memcache) SVN_ERR(svn_cache__create_memcache(&(ffd->rev_root_id_cache), memcache, serialize_id, deserialize_id, sizeof(svn_revnum_t), apr_pstrcat(pool, prefix, "RRI", NULL), fs->pool)); else SVN_ERR(svn_cache__create_inprocess(&(ffd->rev_root_id_cache), dup_id, sizeof(svn_revnum_t), 1, 100, FALSE, fs->pool)); if (! no_handler) SVN_ERR(svn_cache__set_error_handler(ffd->rev_root_id_cache, warn_on_cache_errors, fs, pool)); /* Rough estimate: revision DAG nodes have size around 320 bytes, so * let's put 16 on a page. */ if (memcache) SVN_ERR(svn_cache__create_memcache(&(ffd->rev_node_cache), memcache, svn_fs_fs__dag_serialize, svn_fs_fs__dag_deserialize, APR_HASH_KEY_STRING, apr_pstrcat(pool, prefix, "DAG", NULL), fs->pool)); else SVN_ERR(svn_cache__create_inprocess(&(ffd->rev_node_cache), svn_fs_fs__dag_dup_for_cache, APR_HASH_KEY_STRING, 1024, 16, FALSE, fs->pool)); if (! no_handler) SVN_ERR(svn_cache__set_error_handler(ffd->rev_node_cache, warn_on_cache_errors, fs, pool)); /* Very rough estimate: 1K per directory. */ if (memcache) SVN_ERR(svn_cache__create_memcache(&(ffd->dir_cache), memcache, svn_fs_fs__dir_entries_serialize, svn_fs_fs__dir_entries_deserialize, APR_HASH_KEY_STRING, apr_pstrcat(pool, prefix, "DIR", NULL), fs->pool)); else SVN_ERR(svn_cache__create_inprocess(&(ffd->dir_cache), dup_dir_listing, APR_HASH_KEY_STRING, 1024, 8, FALSE, fs->pool)); if (! no_handler) SVN_ERR(svn_cache__set_error_handler(ffd->dir_cache, warn_on_cache_errors, fs, pool)); /* Only 16 bytes per entry (a revision number + the corresponding offset). Since we want ~8k pages, that means 512 entries per page. */ if (memcache) SVN_ERR(svn_cache__create_memcache(&(ffd->packed_offset_cache), memcache, manifest_serialize, manifest_deserialize, sizeof(svn_revnum_t), apr_pstrcat(pool, prefix, "PACK-MANIFEST", NULL), fs->pool)); else SVN_ERR(svn_cache__create_inprocess(&(ffd->packed_offset_cache), dup_pack_manifest, sizeof(svn_revnum_t), 32, 1, FALSE, fs->pool)); if (! no_handler) SVN_ERR(svn_cache__set_error_handler(ffd->packed_offset_cache, warn_on_cache_errors, fs, pool)); if (memcache) { SVN_ERR(svn_cache__create_memcache(&(ffd->fulltext_cache), memcache, /* Values are svn_string_t */ NULL, NULL, APR_HASH_KEY_STRING, apr_pstrcat(pool, prefix, "TEXT", NULL), fs->pool)); if (! no_handler) SVN_ERR(svn_cache__set_error_handler(ffd->fulltext_cache, warn_on_cache_errors, fs, pool)); } else ffd->fulltext_cache = NULL; return SVN_NO_ERROR; }