From: Arvin Schnell Date: Thu, 11 Dec 2014 17:01:42 +0000 (+0100) Subject: - support weekly snapshots in cleanup algorithm X-Git-Tag: v0.2.5~5^2~2 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=595aa52cf892f7ebc4d27f67e60f2fedf8b393b6;p=thirdparty%2Fsnapper.git - support weekly snapshots in cleanup algorithm --- diff --git a/client/cleanup.cc b/client/cleanup.cc index cd48e70d..8d2d77c7 100644 --- a/client/cleanup.cc +++ b/client/cleanup.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) [2011-2013] Novell, Inc. + * Copyright (c) [2011-2014] Novell, Inc. * * All Rights Reserved. * @@ -24,6 +24,8 @@ #include +#include "utils/equal-date.h" + #include "commands.h" using namespace std; @@ -188,31 +190,6 @@ is_first(list::const_iterator first, } -bool -equal_year(const struct tm& tmp1, const struct tm& tmp2) -{ - return tmp1.tm_year == tmp2.tm_year; -} - -bool -equal_month(const struct tm& tmp1, const struct tm& tmp2) -{ - return equal_year(tmp1, tmp2) && tmp1.tm_mon == tmp2.tm_mon; -} - -bool -equal_day(const struct tm& tmp1, const struct tm& tmp2) -{ - return equal_month(tmp1, tmp2) && tmp1.tm_mday == tmp2.tm_mday; -} - -bool -equal_hour(const struct tm& tmp1, const struct tm& tmp2) -{ - return equal_day(tmp1, tmp2) && tmp1.tm_hour == tmp2.tm_hour; -} - - bool is_first_yearly(list::const_iterator first, list::const_iterator last, @@ -229,6 +206,14 @@ is_first_monthly(list::const_iterator first, return is_first(first, last, it1, equal_month); } +bool +is_first_weekly(list::const_iterator first, + list::const_iterator last, + XSnapshots::const_iterator it1) +{ + return is_first(first, last, it1, equal_week); +} + bool is_first_daily(list::const_iterator first, list::const_iterator last, @@ -253,6 +238,7 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name) size_t limit_hourly = 10; size_t limit_daily = 10; size_t limit_monthly = 10; + size_t limit_weekly = 0; size_t limit_yearly = 10; XConfigInfo ci = command_get_xconfig(conn, config_name); @@ -263,6 +249,8 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name) pos->second >> limit_hourly; if ((pos = ci.raw.find("TIMELINE_LIMIT_DAILY")) != ci.raw.end()) pos->second >> limit_daily; + if ((pos = ci.raw.find("TIMELINE_LIMIT_WEEKLY")) != ci.raw.end()) + pos->second >> limit_weekly; if ((pos = ci.raw.find("TIMELINE_LIMIT_MONTHLY")) != ci.raw.end()) pos->second >> limit_monthly; if ((pos = ci.raw.find("TIMELINE_LIMIT_YEARLY")) != ci.raw.end()) @@ -270,6 +258,7 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name) size_t num_hourly = 0; size_t num_daily = 0; + size_t num_weekly = 0; size_t num_monthly = 0; size_t num_yearly = 0; @@ -298,6 +287,11 @@ do_cleanup_timeline(DBus::Connection& conn, const string& config_name) ++num_daily; keep = true; } + if (num_weekly < limit_weekly && is_first_weekly(it, tmp.end(), *it)) + { + ++num_weekly; + keep = true; + } if (num_monthly < limit_monthly && is_first_monthly(it, tmp.end(), *it)) { ++num_monthly; diff --git a/client/utils/Makefile.am b/client/utils/Makefile.am index aeda1fae..020137dc 100644 --- a/client/utils/Makefile.am +++ b/client/utils/Makefile.am @@ -10,6 +10,7 @@ libutils_la_SOURCES = \ Table.cc Table.h \ text.cc text.h \ console.cc console.h \ + equal-date.cc equal-date.h \ GetOpts.cc GetOpts.h libutils_la_LIBADD = ../../snapper/libsnapper.la diff --git a/client/utils/equal-date.cc b/client/utils/equal-date.cc new file mode 100644 index 00000000..b367c64b --- /dev/null +++ b/client/utils/equal-date.cc @@ -0,0 +1,83 @@ +/* + * Copyright (c) [2011-2014] Novell, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +#include + +#include "equal-date.h" + + +int +yday_of_weeks_monday(const struct tm& tmp) +{ + return tmp.tm_yday - (tmp.tm_wday != 0 ? tmp.tm_wday : 7); +} + + +int +days_in_year(const struct tm& tmp) +{ + return __isleap(tmp.tm_year) ? 366 : 365; +} + + +bool +equal_year(const struct tm& tmp1, const struct tm& tmp2) +{ + return tmp1.tm_year == tmp2.tm_year; +} + + +bool +equal_month(const struct tm& tmp1, const struct tm& tmp2) +{ + return equal_year(tmp1, tmp2) && tmp1.tm_mon == tmp2.tm_mon; +} + + +bool +equal_week(const struct tm& tmp1, const struct tm& tmp2) +{ + if (tmp1.tm_year == tmp2.tm_year) + return yday_of_weeks_monday(tmp1) == yday_of_weeks_monday(tmp2); + + if (tmp1.tm_year + 1 == tmp2.tm_year) + return yday_of_weeks_monday(tmp1) == yday_of_weeks_monday(tmp2) + days_in_year(tmp1); + + if (tmp1.tm_year == tmp2.tm_year + 1) + return yday_of_weeks_monday(tmp1) + days_in_year(tmp2) == yday_of_weeks_monday(tmp2); + + return false; +} + + +bool +equal_day(const struct tm& tmp1, const struct tm& tmp2) +{ + return equal_month(tmp1, tmp2) && tmp1.tm_mday == tmp2.tm_mday; +} + + +bool +equal_hour(const struct tm& tmp1, const struct tm& tmp2) +{ + return equal_day(tmp1, tmp2) && tmp1.tm_hour == tmp2.tm_hour; +} diff --git a/client/utils/equal-date.h b/client/utils/equal-date.h new file mode 100644 index 00000000..51ec49aa --- /dev/null +++ b/client/utils/equal-date.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) [2011-2014] Novell, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +bool +equal_year(const struct tm& tmp1, const struct tm& tmp2); + +bool +equal_month(const struct tm& tmp1, const struct tm& tmp2); + +bool +equal_week(const struct tm& tmp1, const struct tm& tmp2); + +bool +equal_day(const struct tm& tmp1, const struct tm& tmp2); + +bool +equal_hour(const struct tm& tmp1, const struct tm& tmp2); + diff --git a/data/default-config b/data/default-config index 76ddd47e..1e3b78d2 100644 --- a/data/default-config +++ b/data/default-config @@ -39,6 +39,7 @@ TIMELINE_CLEANUP="yes" TIMELINE_MIN_AGE="1800" TIMELINE_LIMIT_HOURLY="10" TIMELINE_LIMIT_DAILY="10" +TIMELINE_LIMIT_WEEKLY="0" TIMELINE_LIMIT_MONTHLY="10" TIMELINE_LIMIT_YEARLY="10" diff --git a/doc/snapper-configs.xml.in b/doc/snapper-configs.xml.in index 538fb4d0..9713bbc6 100644 --- a/doc/snapper-configs.xml.in +++ b/doc/snapper-configs.xml.in @@ -187,6 +187,16 @@ + + + + Defines how many weekly snapshots the timeline cleanup + algorithm should keep. A weekly snapshot is the first snapshot in a week. The + youngest weekly snapshots will be kept. + Default value is "0". + + + diff --git a/doc/snapper.xml.in b/doc/snapper.xml.in index 09d17051..e1572a2a 100644 --- a/doc/snapper.xml.in +++ b/doc/snapper.xml.in @@ -124,7 +124,7 @@ timeline Deletes old snapshots but keeps a number of hourly, daily, - monthly and yearly snapshots. + weekly, monthly and yearly snapshots. diff --git a/package/snapper.changes b/package/snapper.changes index d849f8b4..b9aad17f 100644 --- a/package/snapper.changes +++ b/package/snapper.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Dec 11 17:58:14 CET 2014 - aschnell@suse.de + +- support weekly snapshots in cleanup algorithm (see + gh#openSUSE/snapper#135) + ------------------------------------------------------------------- Thu Oct 23 12:05:12 CEST 2014 - aschnell@suse.de diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 39d94e9f..85f0d0bb 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -1,7 +1,5 @@ *.log *.o +*.test *.trs -basename1 -dirname1 -sysconfig-get1 test-suite.log diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index df6db5a1..f0f38d8d 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -6,7 +6,7 @@ INCLUDES = -I$(top_srcdir) LDADD = ../snapper/libsnapper.la -lboost_unit_test_framework -check_PROGRAMS = sysconfig-get1 dirname1 basename1 +check_PROGRAMS = sysconfig-get1.test dirname1.test basename1.test equal-date.test TESTS = $(check_PROGRAMS) @@ -14,3 +14,5 @@ AM_DEFAULT_SOURCE_EXT = .cc EXTRA_DIST = $(noinst_SCRIPTS) sysconfig-get1.txt +equal_date_test_LDADD = -lboost_unit_test_framework ../client/utils/libutils.la + diff --git a/testsuite/equal-date.cc b/testsuite/equal-date.cc new file mode 100644 index 00000000..42e00d8d --- /dev/null +++ b/testsuite/equal-date.cc @@ -0,0 +1,70 @@ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE snapper + +#include + +#include "../client/utils/equal-date.h" + + +bool +equal_week(const char* s1, const char* s2) +{ + struct tm tmp1; + memset(&tmp1, 0, sizeof(tmp1)); + strptime(s1, "%Y-%m-%d", &tmp1); + + struct tm tmp2; + memset(&tmp2, 0, sizeof(tmp2)); + strptime(s2, "%Y-%m-%d", &tmp2); + + return equal_week(tmp1, tmp2); +} + + +BOOST_AUTO_TEST_CASE(test1) +{ + // 2012 is a leap year + BOOST_CHECK(equal_week("2011-12-31", "2012-01-01")); + BOOST_CHECK(equal_week("2012-01-01", "2011-12-31")); +} + + +BOOST_AUTO_TEST_CASE(test2) +{ + // 2012 is a leap year + BOOST_CHECK(equal_week("2012-12-31", "2013-01-01")); + BOOST_CHECK(equal_week("2013-01-01", "2012-12-31")); +} + + +BOOST_AUTO_TEST_CASE(test3) +{ + // Saturday and Sunday + BOOST_CHECK(equal_week("2014-01-04", "2014-01-05")); + BOOST_CHECK(equal_week("2014-01-05", "2014-01-04")); + + // Sunday and Monday + BOOST_CHECK(!equal_week("2014-01-05", "2014-01-06")); + BOOST_CHECK(!equal_week("2014-01-06", "2014-01-05")); + + // Monday and Tuesday + BOOST_CHECK(equal_week("2014-01-06", "2014-01-07")); + BOOST_CHECK(equal_week("2014-01-07", "2014-01-06")); +} + + +BOOST_AUTO_TEST_CASE(test4) +{ + // 2014-12-31 is a Wednesday, 2015-01-01 is a Thursday + BOOST_CHECK(equal_week("2014-12-31", "2015-01-01")); + BOOST_CHECK(equal_week("2015-01-01", "2014-12-31")); +} + + +BOOST_AUTO_TEST_CASE(test5) +{ + // 2017-12-31 is a Sunday, 2018-01-01 is a Monday + BOOST_CHECK(!equal_week("2017-12-31", "2018-01-01")); + BOOST_CHECK(!equal_week("2018-01-01", "2017-12-31")); +}