Deleted Added
full compact
rep-cache.c (322442) rep-cache.c (362181)
1/* rep-sharing.c --- the rep-sharing cache for fsfs
2 *
3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the

--- 10 unchanged lines hidden (view full) ---

19 * under the License.
20 * ====================================================================
21 */
22
23#include "svn_pools.h"
24
25#include "svn_private_config.h"
26
1/* rep-sharing.c --- the rep-sharing cache for fsfs
2 *
3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the

--- 10 unchanged lines hidden (view full) ---

19 * under the License.
20 * ====================================================================
21 */
22
23#include "svn_pools.h"
24
25#include "svn_private_config.h"
26
27#include "cached_data.h"
27#include "fs_fs.h"
28#include "fs.h"
29#include "rep-cache.h"
30#include "../libsvn_fs/fs-loader.h"
31
32#include "svn_path.h"
33
34#include "private/svn_sqlite.h"
35
36#include "rep-cache-db.h"
37
28#include "fs_fs.h"
29#include "fs.h"
30#include "rep-cache.h"
31#include "../libsvn_fs/fs-loader.h"
32
33#include "svn_path.h"
34
35#include "private/svn_sqlite.h"
36
37#include "rep-cache-db.h"
38
38/* A few magic values */
39#define REP_CACHE_SCHEMA_FORMAT 1
40
41REP_CACHE_DB_SQL_DECLARE_STATEMENTS(statements);
42
43
44
45/** Helper functions. **/
46static APR_INLINE const char *
47path_rep_cache_db(const char *fs_path,
48 apr_pool_t *result_pool)
49{
50 return svn_dirent_join(fs_path, REP_CACHE_DB_NAME, result_pool);
51}
52
39REP_CACHE_DB_SQL_DECLARE_STATEMENTS(statements);
40
41
42
43/** Helper functions. **/
44static APR_INLINE const char *
45path_rep_cache_db(const char *fs_path,
46 apr_pool_t *result_pool)
47{
48 return svn_dirent_join(fs_path, REP_CACHE_DB_NAME, result_pool);
49}
50
53#define SVN_ERR_CLOSE(x, db) do \
54{ \
55 svn_error_t *svn__err = (x); \
56 if (svn__err) \
57 return svn_error_compose_create(svn__err, svn_sqlite__close(db)); \
58} while (0)
59
60
61/** Library-private API's. **/
62
63/* Body of svn_fs_fs__open_rep_cache().
64 Implements svn_atomic__init_once().init_func.
65 */
66static svn_error_t *
67open_rep_cache(void *baton,

--- 33 unchanged lines hidden (view full) ---

101 }
102 }
103#endif
104 SVN_ERR(svn_sqlite__open(&sdb, db_path,
105 svn_sqlite__mode_rwcreate, statements,
106 0, NULL, 0,
107 fs->pool, pool));
108
51
52/** Library-private API's. **/
53
54/* Body of svn_fs_fs__open_rep_cache().
55 Implements svn_atomic__init_once().init_func.
56 */
57static svn_error_t *
58open_rep_cache(void *baton,

--- 33 unchanged lines hidden (view full) ---

92 }
93 }
94#endif
95 SVN_ERR(svn_sqlite__open(&sdb, db_path,
96 svn_sqlite__mode_rwcreate, statements,
97 0, NULL, 0,
98 fs->pool, pool));
99
109 SVN_ERR_CLOSE(svn_sqlite__read_schema_version(&version, sdb, pool), sdb);
110 if (version < REP_CACHE_SCHEMA_FORMAT)
100 SVN_SQLITE__ERR_CLOSE(svn_sqlite__read_schema_version(&version, sdb, pool),
101 sdb);
102 /* If we have an uninitialized database, go ahead and create the schema. */
103 if (version <= 0)
111 {
104 {
112 /* Must be 0 -- an uninitialized (no schema) database. Create
113 the schema. Results in schema version of 1. */
114 SVN_ERR_CLOSE(svn_sqlite__exec_statements(sdb, STMT_CREATE_SCHEMA), sdb);
105 int stmt;
106
107 if (ffd->format >= SVN_FS_FS__MIN_REP_CACHE_SCHEMA_V2_FORMAT)
108 stmt = STMT_CREATE_SCHEMA_V2;
109 else
110 stmt = STMT_CREATE_SCHEMA_V1;
111
112 SVN_SQLITE__ERR_CLOSE(svn_sqlite__exec_statements(sdb, stmt), sdb);
115 }
116
117 /* This is used as a flag that the database is available so don't
118 set it earlier. */
119 ffd->rep_cache_db = sdb;
120
121 return SVN_NO_ERROR;
122}

--- 135 unchanged lines hidden (view full) ---

258 return SVN_NO_ERROR;
259}
260
261
262/* This function's caller ignores most errors it returns.
263 If you extend this function, check the callsite to see if you have
264 to make it not-ignore additional error codes. */
265svn_error_t *
113 }
114
115 /* This is used as a flag that the database is available so don't
116 set it earlier. */
117 ffd->rep_cache_db = sdb;
118
119 return SVN_NO_ERROR;
120}

--- 135 unchanged lines hidden (view full) ---

256 return SVN_NO_ERROR;
257}
258
259
260/* This function's caller ignores most errors it returns.
261 If you extend this function, check the callsite to see if you have
262 to make it not-ignore additional error codes. */
263svn_error_t *
266svn_fs_fs__get_rep_reference(representation_t **rep,
264svn_fs_fs__get_rep_reference(representation_t **rep_p,
267 svn_fs_t *fs,
268 svn_checksum_t *checksum,
269 apr_pool_t *pool)
270{
271 fs_fs_data_t *ffd = fs->fsap_data;
272 svn_sqlite__stmt_t *stmt;
273 svn_boolean_t have_row;
265 svn_fs_t *fs,
266 svn_checksum_t *checksum,
267 apr_pool_t *pool)
268{
269 fs_fs_data_t *ffd = fs->fsap_data;
270 svn_sqlite__stmt_t *stmt;
271 svn_boolean_t have_row;
272 representation_t *rep;
274
275 SVN_ERR_ASSERT(ffd->rep_sharing_allowed);
276 if (! ffd->rep_cache_db)
277 SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
278
279 /* We only allow SHA1 checksums in this table. */
280 if (checksum->kind != svn_checksum_sha1)
281 return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
282 _("Only SHA1 checksums can be used as keys in the "
283 "rep_cache table.\n"));
284
285 SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db, STMT_GET_REP));
286 SVN_ERR(svn_sqlite__bindf(stmt, "s",
287 svn_checksum_to_cstring(checksum, pool)));
288
289 SVN_ERR(svn_sqlite__step(&have_row, stmt));
290 if (have_row)
291 {
273
274 SVN_ERR_ASSERT(ffd->rep_sharing_allowed);
275 if (! ffd->rep_cache_db)
276 SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
277
278 /* We only allow SHA1 checksums in this table. */
279 if (checksum->kind != svn_checksum_sha1)
280 return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
281 _("Only SHA1 checksums can be used as keys in the "
282 "rep_cache table.\n"));
283
284 SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db, STMT_GET_REP));
285 SVN_ERR(svn_sqlite__bindf(stmt, "s",
286 svn_checksum_to_cstring(checksum, pool)));
287
288 SVN_ERR(svn_sqlite__step(&have_row, stmt));
289 if (have_row)
290 {
292 *rep = apr_pcalloc(pool, sizeof(**rep));
293 svn_fs_fs__id_txn_reset(&(*rep)->txn_id);
294 memcpy((*rep)->sha1_digest, checksum->digest,
295 sizeof((*rep)->sha1_digest));
296 (*rep)->has_sha1 = TRUE;
297 (*rep)->revision = svn_sqlite__column_revnum(stmt, 0);
298 (*rep)->item_index = svn_sqlite__column_int64(stmt, 1);
299 (*rep)->size = svn_sqlite__column_int64(stmt, 2);
300 (*rep)->expanded_size = svn_sqlite__column_int64(stmt, 3);
291 rep = apr_pcalloc(pool, sizeof(*rep));
292 svn_fs_fs__id_txn_reset(&(rep->txn_id));
293 memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest));
294 rep->has_sha1 = TRUE;
295 rep->revision = svn_sqlite__column_revnum(stmt, 0);
296 rep->item_index = svn_sqlite__column_int64(stmt, 1);
297 rep->size = svn_sqlite__column_int64(stmt, 2);
298 rep->expanded_size = svn_sqlite__column_int64(stmt, 3);
301 }
302 else
299 }
300 else
303 *rep = NULL;
301 rep = NULL;
304
305 SVN_ERR(svn_sqlite__reset(stmt));
306
302
303 SVN_ERR(svn_sqlite__reset(stmt));
304
307 if (*rep)
305 if (rep)
308 {
306 {
307 svn_error_t *err;
308
309 SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, rep, pool));
310
309 /* Check that REP refers to a revision that exists in FS. */
311 /* Check that REP refers to a revision that exists in FS. */
310 svn_error_t *err = svn_fs_fs__ensure_revision_exists((*rep)->revision,
311 fs, pool);
312 err = svn_fs_fs__ensure_revision_exists(rep->revision, fs, pool);
312 if (err)
313 return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
314 "Checksum '%s' in rep-cache is beyond HEAD",
315 svn_checksum_to_cstring_display(checksum,
316 pool));
317 }
318
313 if (err)
314 return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
315 "Checksum '%s' in rep-cache is beyond HEAD",
316 svn_checksum_to_cstring_display(checksum,
317 pool));
318 }
319
320 *rep_p = rep;
319 return SVN_NO_ERROR;
320}
321
322svn_error_t *
323svn_fs_fs__set_rep_reference(svn_fs_t *fs,
324 representation_t *rep,
325 apr_pool_t *pool)
326{
327 fs_fs_data_t *ffd = fs->fsap_data;
328 svn_sqlite__stmt_t *stmt;
321 return SVN_NO_ERROR;
322}
323
324svn_error_t *
325svn_fs_fs__set_rep_reference(svn_fs_t *fs,
326 representation_t *rep,
327 apr_pool_t *pool)
328{
329 fs_fs_data_t *ffd = fs->fsap_data;
330 svn_sqlite__stmt_t *stmt;
329 svn_error_t *err;
330 svn_checksum_t checksum;
331 checksum.kind = svn_checksum_sha1;
332 checksum.digest = rep->sha1_digest;
333
334 SVN_ERR_ASSERT(ffd->rep_sharing_allowed);
335 if (! ffd->rep_cache_db)
336 SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
337

--- 6 unchanged lines hidden (view full) ---

344 SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db, STMT_SET_REP));
345 SVN_ERR(svn_sqlite__bindf(stmt, "siiii",
346 svn_checksum_to_cstring(&checksum, pool),
347 (apr_int64_t) rep->revision,
348 (apr_int64_t) rep->item_index,
349 (apr_int64_t) rep->size,
350 (apr_int64_t) rep->expanded_size));
351
331 svn_checksum_t checksum;
332 checksum.kind = svn_checksum_sha1;
333 checksum.digest = rep->sha1_digest;
334
335 SVN_ERR_ASSERT(ffd->rep_sharing_allowed);
336 if (! ffd->rep_cache_db)
337 SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
338

--- 6 unchanged lines hidden (view full) ---

345 SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db, STMT_SET_REP));
346 SVN_ERR(svn_sqlite__bindf(stmt, "siiii",
347 svn_checksum_to_cstring(&checksum, pool),
348 (apr_int64_t) rep->revision,
349 (apr_int64_t) rep->item_index,
350 (apr_int64_t) rep->size,
351 (apr_int64_t) rep->expanded_size));
352
352 err = svn_sqlite__insert(NULL, stmt);
353 if (err)
354 {
355 representation_t *old_rep;
353 SVN_ERR(svn_sqlite__insert(NULL, stmt));
356
354
357 if (err->apr_err != SVN_ERR_SQLITE_CONSTRAINT)
358 return svn_error_trace(err);
359
360 svn_error_clear(err);
361
362 /* Constraint failed so the mapping for SHA1_CHECKSUM->REP
363 should exist. If so that's cool -- just do nothing. If not,
364 that's a red flag! */
365 SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, fs, &checksum, pool));
366
367 if (!old_rep)
368 {
369 /* Something really odd at this point, we failed to insert the
370 checksum AND failed to read an existing checksum. Do we need
371 to flag this? */
372 }
373 }
374
375 return SVN_NO_ERROR;
376}
377
378
379svn_error_t *
380svn_fs_fs__del_rep_reference(svn_fs_t *fs,
381 svn_revnum_t youngest,
382 apr_pool_t *pool)

--- 61 unchanged lines hidden ---
355 return SVN_NO_ERROR;
356}
357
358
359svn_error_t *
360svn_fs_fs__del_rep_reference(svn_fs_t *fs,
361 svn_revnum_t youngest,
362 apr_pool_t *pool)

--- 61 unchanged lines hidden ---