Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Use short checksum for files in cache.
Vsevolod Stakhov committed 12 years ago
commit e6242579fbdb94c4eed9d6a2f6a0df8d1024fa72
parent cba6720
6 files changed +99 -14
modified libpkg/pkg.h.in
@@ -1638,4 +1638,22 @@ struct sbuf *pkg_sbuf_vprintf(struct sbuf * restrict sbuf,
bool pkg_has_message(struct pkg *p);
bool pkg_is_locked(const struct pkg * restrict p);

+

+
/**
+
 * Defines how many chars of checksum are there in a package's name
+
 * We define this number as sufficient for 24k packages.
+
 * To find out probability of collision it is possible to use the following
+
 * python function to calculate 'birthday paradox' probability:
+
 *  def bp(m, n):
+
 *      power = -(n * n) / (2. * m)
+
 *      return 1. - exp(power)
+
 * 
+
 * For our choice of 2^40 (or 10 hex characters) it is:
+
 *  >>> bp(float(2 ** 40), 24500.)
+
 *  0.00027292484660568217
+
 * 
+
 * And it is negligible probability
+
 */ 
+
#define PKG_FILE_CKSUM_CHARS 10
+

#endif
modified libpkg/pkg_jobs.c
@@ -1856,7 +1856,8 @@ pkg_jobs_handle_install(struct pkg_solved *ps, struct pkg_jobs *j, bool handle_r
	else {
		pkg_snprintf(path, sizeof(path), "%R", new);
		if (*path != '/')
-
			pkg_snprintf(path, sizeof(path), "%S/%u", cachedir, new);
+
			pkg_snprintf(path, sizeof(path), "%S/%n-%v-%z",
+
					cachedir, new, new, new);
		target = path;
	}

@@ -2089,7 +2090,8 @@ pkg_jobs_apply(struct pkg_jobs *j)
				continue;															\
			int64_t pkgsize;														\
			pkg_get(p, PKG_PKGSIZE, &pkgsize);				\
-
			pkg_snprintf(cachedpath, sizeof(cachedpath), "%S/%u", cachedir, p);	\
+
			pkg_snprintf(cachedpath, sizeof(cachedpath), "%S/%n-%v-%z", \
+
				cachedir, p, p, p);													\
			if (stat(cachedpath, &st) == -1)										\
				dlsize += pkgsize;													\
			else																	\
@@ -2186,7 +2188,8 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)
			if (p->type == PKG_REMOTE) {
				pkg_snprintf(path, sizeof(path), "%R", p);
				if (*path != '/')
-
					pkg_snprintf(path, sizeof(path), "%S/%u", cachedir, p);
+
					pkg_snprintf(path, sizeof(path), "%S/%n-%v-%z",
+
							cachedir, p, p, p);
				if (pkg_open(&pkg, path, keys, 0) != EPKG_OK)
					return (EPKG_FATAL);
				p = pkg;
modified libpkg/pkg_printf.c
@@ -155,7 +155,8 @@
 *
 * x
 * y
-
 * z
+
 *
+
 * z  pkg          short checksum
 */

struct pkg_printf_fmt {
@@ -758,6 +759,15 @@ static const struct pkg_printf_fmt fmt[] = {
		PP_ALL,
		&format_checksum,
	},
+
	[PP_PKG_SHORT_CHECKSUM] =
+
	{
+
		'z',
+
		'\0',
+
		false,
+
		true,
+
		PP_ALL,
+
		&format_short_checksum,
+
	},
	[PP_PKG_VERSION] =
	{
		'v',
@@ -1818,6 +1828,26 @@ format_checksum(struct sbuf *sbuf, const void *data, struct percent_esc *p)
}

/*
+
 * %z -- Package short checksum. string. Accepts field width, left align
+
 */
+
struct sbuf *
+
format_short_checksum(struct sbuf *sbuf, const void *data, struct percent_esc *p)
+
{
+
	const struct pkg	*pkg = data;
+
	const char		*checksum;
+
	char	 csum[PKG_FILE_CKSUM_CHARS + 1];
+
	int slen;
+

+
	pkg_get(pkg, PKG_CKSUM, &checksum);
+

+
	slen = MIN(PKG_FILE_CKSUM_CHARS, strlen(checksum));
+
	memcpy(csum, checksum, slen);
+
	csum[slen] = '\0';
+

+
	return (string_val(sbuf, csum, p));
+
}
+

+
/*
 * %w -- Home page URL.  string.  Accepts field width, left align
 */
struct sbuf *
modified libpkg/pkg_repo.c
@@ -73,7 +73,8 @@ pkg_repo_fetch(struct pkg *pkg)
	pkg_get(pkg, PKG_REPONAME, &reponame,
	    PKG_CKSUM, &sum, PKG_NAME, &name, PKG_VERSION, &version);

-
	pkg_snprintf(dest, sizeof(dest), "%S/%u", cachedir, pkg);
+
	pkg_snprintf(dest, sizeof(dest), "%S/%n-%v-%z",
+
			cachedir, pkg, pkg, pkg);

	/* If it is already in the local cachedir, dont bother to
	 * download it */
modified libpkg/private/pkg_printf.h
@@ -141,10 +141,11 @@ typedef enum _fmt_code_t {
	PP_PKG_CHECKSUM,
	PP_PKG_VERSION,
	PP_PKG_HOME_PAGE,
-
	PP_LAST_FORMAT = PP_PKG_HOME_PAGE,
+
	PP_PKG_SHORT_CHECKSUM,
+
	PP_LAST_FORMAT = PP_PKG_SHORT_CHECKSUM,
	PP_LITERAL_PERCENT,
	PP_UNKNOWN,
-
	PP_END_MARKER,
+
	PP_END_MARKER
} fmt_code_t;

#define	ITEM_FMT_SET	(0x1U << 0)
@@ -221,6 +222,7 @@ _static struct sbuf *format_requirements(struct sbuf *, const void *, struct per
_static struct sbuf *format_flatsize(struct sbuf *, const void *, struct percent_esc *);
_static struct sbuf *format_install_tstamp(struct sbuf *, const void *, struct percent_esc *);
_static struct sbuf *format_checksum(struct sbuf *, const void *, struct percent_esc *);
+
_static struct sbuf *format_short_checksum(struct sbuf *, const void *, struct percent_esc *);
_static struct sbuf *format_version(struct sbuf *, const void *, struct percent_esc *);
_static struct sbuf *format_home_url(struct sbuf *, const void *, struct percent_esc *);
_static struct sbuf *format_literal_percent(struct sbuf *, __unused const void *, __unused struct percent_esc *);
modified src/clean.c
@@ -1,6 +1,7 @@
/*-
 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
+
 * Copyright (c) 2014 Vsevolod Stakhov <vsevolod@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,8 @@

#include <sys/stat.h>
#include <sys/queue.h>
+
/* For MIN */
+
#include <sys/param.h>

#include <assert.h>
#include <err.h>
@@ -47,7 +50,7 @@ struct deletion_list {
};

struct sumlist {
-
	char *sum;
+
	char sum[PKG_FILE_CKSUM_CHARS + 1];
	UT_hash_handle hh;
};

@@ -118,6 +121,31 @@ delete_dellist(struct dl_head *dl)
	return (retcode);
}

+
/*
+
 * Extract hash from filename in format <name>-<version>-<hash>.txz
+
 */
+
static bool
+
extract_filename_sum(const char *fname, char sum[])
+
{
+
	const char *dash_pos, *dot_pos;
+

+
	dot_pos = strrchr(fname, '.');
+
	if (dot_pos == NULL)
+
		dot_pos = fname + strlen(fname);
+

+
	dash_pos = strrchr(fname, '-');
+
	if (dash_pos == NULL)
+
		return (false);
+
	else if (dot_pos < dash_pos)
+
		dot_pos = fname + strlen(fname);
+

+
	if (dot_pos - dash_pos != PKG_FILE_CKSUM_CHARS + 1)
+
		return (false);
+

+
	strlcpy(sum, dash_pos + 1, PKG_FILE_CKSUM_CHARS + 1);
+
	return (true);
+
}
+

void
usage_clean(void)
{
@@ -136,14 +164,14 @@ exec_clean(int argc, char **argv)
	FTSENT		*ent = NULL;
	struct dl_head	dl = STAILQ_HEAD_INITIALIZER(dl);
	const char	*cachedir, *sum;
-
	char		*paths[2];
+
	char		*paths[2], csum[PKG_FILE_CKSUM_CHARS + 1];
	bool		 all = false;
	bool		 dry_run = false;
	bool		 yes, sumloaded = false;
	int		 retcode;
	int		 ret;
	int		 ch;
-
	size_t		 total = 0;
+
	size_t		 total = 0, slen;
	char		 size[7];
	struct pkg_manifest_key *keys = NULL;

@@ -222,16 +250,20 @@ exec_clean(int argc, char **argv)
			it = pkgdb_search(db, "*", MATCH_GLOB, FIELD_NAME, FIELD_NONE, NULL);
			while (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) == EPKG_OK) {
				pkg_get(p, PKG_CKSUM, &sum);
+
				slen = MIN(strlen(sum), PKG_FILE_CKSUM_CHARS);
				s = calloc(1, sizeof(struct sumlist));
-
				s->sum = strdup(sum);
-
				HASH_ADD_KEYPTR(hh, sumlist, s->sum, strlen(s->sum), s);
+
				memcpy(s->sum, sum, slen);
+
				s->sum[slen] = '\0';
+
				HASH_ADD_STR(sumlist, sum, s);
			}
			pkgdb_it_free(it);
			pkgdb_release_lock(db, PKGDB_LOCK_READONLY);
			pkgdb_close(db);
		}

-
		HASH_FIND_STR(sumlist, ent->fts_name, s);
+
		s = NULL;
+
		if (extract_filename_sum(ent->fts_name, csum))
+
			HASH_FIND_STR(sumlist, csum, s);
		if (s == NULL) {
			ret = add_to_dellist(&dl, ent->fts_path);
			total += ent->fts_statp->st_size;
@@ -240,7 +272,6 @@ exec_clean(int argc, char **argv)
	}
	HASH_ITER(hh, sumlist, s, t) {
		HASH_DEL(sumlist, s);
-
		free(s->sum);
		free(s);
	}