Algorithm-History-Levels

 view release on metacpan or  search on metacpan

lib/Algorithm/History/Levels.pm  view on Meta::CPAN

explained by an example. Suppose you produce daily database backups. Your backup
files are named:

    mydb.2017-06-13.sql.gz
    mydb.2017-06-12.sql.gz
    mydb.2017-06-11.sql.gz
    mydb.2017-06-10.sql.gz
    mydb.2017-06-09.sql.gz
    ...

After a while, your backups grow into tens and then hundreds of dump files. You
typically want to keep certain number of backups only, for example: 7 daily
backups, 4 weekly backups, 6 monthly backups (so you practically have 6 months
of history but do not need to store 6*30 = 180 dumps, only 7 + 4 + 6 = 17). This
is the routine you can use to select which files to keep and which to discard.

You provide the list of histories either in the form of Unix timestamps:

    [1497286800, 1497200400, 1497114000, ...]

or in the form of `[name, timestamp]` pairs, e.g.:

    [
      ['mydb.2017-06-13.sql.gz', 1497286800],
      ['mydb.2017-06-12.sql.gz', 1497200400],
      ['mydb.2017-06-11.sql.gz', 1497114000],
      ...
    ]

Duplicates of timestamps are allowed, but duplicates of names are not allowed.
If list of timestamps are given, the name is assumed to be the timestamp itself
and there must not be duplicates.

Then, you specify the levels with a list of `[period, num-in-this-level]` pairs.
For example, 7 daily + 4 weekly + 6 monthly can be specified using:

    [
      [86400, 7],
      [7*86400, 4],
      [30*86400, 6],
    ]

Subsequent level must have greater period than its previous.

This routine will return a hash. The `levels` key will contain the history
names, grouped into levels. The `discard` key will contain list of history names
to discard:

    {
      levels => [

        # histories for the first level
        ['mydb.2017-06-13.sql.gz',
         'mydb.2017-06-12.sql.gz',
         'mydb.2017-06-11.sql.gz',
         'mydb.2017-06-10.sql.gz',
         'mydb.2017-06-09.sql.gz',
         'mydb.2017-06-08.sql.gz',
         'mydb.2017-06-07.sql.gz'],

        # histories for the second level
        ['mydb.2017-06-06.sql.gz',
         'mydb.2017-05-30.sql.gz',
         'mydb.2017-05-23.sql.gz',
         'mydb.2017-05-16.sql.gz'],

        # histories for the third level
        ['mydb.2017-06-05.sql.gz',
         'mydb.2017-05-06.sql.gz',
         'mydb.2017-04-06.sql.gz',
         ...],

      discard => [
        'mydb.2017-06-04.sql.gz',
        'mydb.2017-06-03.sql.gz',
        ...
      ],
    }

_
    args => {
        histories => {
            schema => ['array*', {
                of=>['any*', {
                    of=>[
                        'int*',
                        ['array*', elems=>['str*', 'float*']],
                    ],
                }],
            }],
            req => 1,
        },
        levels => {
            schema => ['array*', {
                of => ['array*', elems => ['float*', 'posint*']],
                min_len => 1,
            }],
            req => 1,
        },
        now => {
            schema => 'int*',
        },
        discard_old_histories => {
            schema => ['bool*'],
            default => 0,
        },
        discard_young_histories => {
            schema => ['bool*'],
            default => 0,
        },
    },
    result_naked => 1,
};
sub group_histories_into_levels {
    require Array::Sample::Partition;

    my %args = @_;

    my $now = $args{now} // time();

    my $histories0 = $args{histories} or die "Please specify histories";

lib/Algorithm/History/Levels.pm  view on Meta::CPAN

explained by an example. Suppose you produce daily database backups. Your backup
files are named:

 mydb.2017-06-13.sql.gz
 mydb.2017-06-12.sql.gz
 mydb.2017-06-11.sql.gz
 mydb.2017-06-10.sql.gz
 mydb.2017-06-09.sql.gz
 ...

After a while, your backups grow into tens and then hundreds of dump files. You
typically want to keep certain number of backups only, for example: 7 daily
backups, 4 weekly backups, 6 monthly backups (so you practically have 6 months
of history but do not need to store 6*30 = 180 dumps, only 7 + 4 + 6 = 17). This
is the routine you can use to select which files to keep and which to discard.

You provide the list of histories either in the form of Unix timestamps:

 [1497286800, 1497200400, 1497114000, ...]

or in the form of C<[name, timestamp]> pairs, e.g.:

 [
   ['mydb.2017-06-13.sql.gz', 1497286800],
   ['mydb.2017-06-12.sql.gz', 1497200400],
   ['mydb.2017-06-11.sql.gz', 1497114000],
   ...
 ]

Duplicates of timestamps are allowed, but duplicates of names are not allowed.
If list of timestamps are given, the name is assumed to be the timestamp itself
and there must not be duplicates.

Then, you specify the levels with a list of C<[period, num-in-this-level]> pairs.
For example, 7 daily + 4 weekly + 6 monthly can be specified using:

 [
   [86400, 7],
   [7*86400, 4],
   [30*86400, 6],
 ]

Subsequent level must have greater period than its previous.

This routine will return a hash. The C<levels> key will contain the history
names, grouped into levels. The C<discard> key will contain list of history names
to discard:

 {
   levels => [
 
     # histories for the first level
     ['mydb.2017-06-13.sql.gz',
      'mydb.2017-06-12.sql.gz',
      'mydb.2017-06-11.sql.gz',
      'mydb.2017-06-10.sql.gz',
      'mydb.2017-06-09.sql.gz',
      'mydb.2017-06-08.sql.gz',
      'mydb.2017-06-07.sql.gz'],
 
     # histories for the second level
     ['mydb.2017-06-06.sql.gz',
      'mydb.2017-05-30.sql.gz',
      'mydb.2017-05-23.sql.gz',
      'mydb.2017-05-16.sql.gz'],
 
     # histories for the third level
     ['mydb.2017-06-05.sql.gz',
      'mydb.2017-05-06.sql.gz',
      'mydb.2017-04-06.sql.gz',
      ...],
 
   discard => [
     'mydb.2017-06-04.sql.gz',
     'mydb.2017-06-03.sql.gz',
     ...
   ],
 }

This function is not exported by default, but exportable.

Arguments ('*' denotes required arguments):

=over 4

=item * B<discard_old_histories> => I<bool> (default: 0)

=item * B<discard_young_histories> => I<bool> (default: 0)

=item * B<histories>* => I<array[int|array]>

=item * B<levels>* => I<array[array]>

=item * B<now> => I<int>

=back

Return value:  (any)

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/Algorithm-History-Levels>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-Algorithm-History-Levels>.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Algorithm-History-Levels>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 SEE ALSO

=head1 AUTHOR

perlancar <perlancar@cpan.org>



( run in 0.988 second using v1.01-cache-2.11-cpan-39bf76dae61 )