Skip to content

Commit

Permalink
increase performance on range section (#18)
Browse files Browse the repository at this point in the history
performance improvement on range objects
  • Loading branch information
peczenyj authored Dec 12, 2023
1 parent 9dc37eb commit 9aa22a6
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 135 deletions.
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- performance improvement: when we parse a range-based consent string now the Parse method is 23% faster, TO_JSON is 9% faster and check vendor consent or legitimate interest is between 122% and 137% faster than the previous version
- remove GDPR::IAB::TCFv2::RangeConsent package
0.082
- increase TO_JSON performance by 76% on bitfields and 3116% on range based vendor section
- add json section 'publisher' and include all publisher restriction, if any, per purpose id, vendor id and restriction type
Expand Down
98 changes: 0 additions & 98 deletions lib/GDPR/IAB/TCFv2/RangeConsent.pm

This file was deleted.

53 changes: 20 additions & 33 deletions lib/GDPR/IAB/TCFv2/RangeSection.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use integer;
use bytes;

use GDPR::IAB::TCFv2::BitUtils qw<is_set get_uint12 get_uint16>;
use GDPR::IAB::TCFv2::RangeConsent;
use Carp qw<croak>;
use Carp qw<croak>;

sub Parse {
my ( $klass, %args ) = @_;
Expand All @@ -32,31 +31,31 @@ sub Parse {

my ( $num_entries, $next_offset ) = get_uint12( $data, $offset );

my @range_consents;
my @ranges;

foreach my $i ( 1 .. $num_entries ) {
my $range_consent;
( $range_consent, $next_offset ) = _parse_range_consent(
my $range;
( $range, $next_offset ) = _parse_range(
$data, $next_offset,
$max_id,
$options,
);

push @range_consents, $range_consent;
push @ranges, $range;
}

my $self = {
range_consents => \@range_consents,
max_id => $max_id,
options => $options,
ranges => \@ranges,
max_id => $max_id,
options => $options,
};

bless $self, $klass;

return ( $self, $next_offset );
}

sub _parse_range_consent {
sub _parse_range {
my ( $data, $initial_bit, $max_id, $options ) = @_;

my $data_size = length($data);
Expand All @@ -77,11 +76,7 @@ sub _parse_range_consent {
"bit $initial_bit range entry exclusion ends at $end, but the max vendor ID is $max_id"
if $end > $max_id;

return GDPR::IAB::TCFv2::RangeConsent->new(
start => $start,
end => $end,
options => $options,
),
return [ $start, $end ],
$next_offset;
}

Expand All @@ -93,12 +88,7 @@ sub _parse_range_consent {
"bit $initial_bit range entry excludes vendor $vendor_id, but only vendors [1, $max_id] are valid"
if $vendor_id > $max_id;

return GDPR::IAB::TCFv2::RangeConsent->new(
start => $vendor_id,
end => $vendor_id,
options => $options,
),
$next_offset;
return [ $vendor_id, $vendor_id ], $next_offset;
}

sub contains {
Expand All @@ -109,8 +99,8 @@ sub contains {

return if $id > $self->{max_id};

foreach my $range_consent ( @{ $self->{range_consents} } ) {
return 1 if $range_consent->contains($id);
foreach my $range ( @{ $self->{ranges} } ) {
return 1 if $range->[0] <= $id && $id <= $range->[1];
}

return 0;
Expand All @@ -120,8 +110,8 @@ sub all {
my $self = shift;

my @vendors;
foreach my $range_consent ( @{ $self->{range_consents} } ) {
push @vendors, @{ $range_consent->all };
foreach my $range ( @{ $self->{ranges} } ) {
push @vendors, $range->[0] .. $range->[1];
}

return \@vendors;
Expand All @@ -133,9 +123,8 @@ sub TO_JSON {
if ( !!$self->{options}->{json}->{compact} ) {
my @vendors;

foreach my $range_consent ( @{ $self->{range_consents} } ) {
push @vendors, @{ $range_consent->TO_JSON }
; # todo use all when we convert back to arrayref
foreach my $range ( @{ $self->{ranges} } ) {
push @vendors, $range->[0] .. $range->[1];
}

return \@vendors;
Expand All @@ -148,8 +137,8 @@ sub TO_JSON {
%map = map { $_ => $false } 1 .. $self->{max_id};
}

foreach my $range_consent ( @{ $self->{range_consents} } ) {
%map = ( %map, %{ $range_consent->TO_JSON } );
foreach my $range ( @{ $self->{ranges} } ) {
%map = ( %map, map { $_ => $true } $range->[0] .. $range->[1] );
}

return \%map;
Expand All @@ -170,7 +159,7 @@ GDPR::IAB::TCFv2::RangeSection - Transparency & Consent String version 2 range s
my ($range_section, $next_offset) = GDPR::IAB::TCFv2::RangeSection->Parse(
data => $data,
offset => 230, # offset for vendor range_consents
offset => 230, # offset for vendor ranges
max_id => $max_id_consent,
);
Expand Down Expand Up @@ -205,5 +194,3 @@ Returns the max vendor id.
=head2 all
Returns an arrayref of all vendors mapped with the bit enabled.
It is a combination of all the responses of L<GDPR::IAB::TCFv2::RangeConsent#all>.
4 changes: 0 additions & 4 deletions t/00-load.t
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ BEGIN {
use_ok('GDPR::IAB::TCFv2::BitField');
use_ok('GDPR::IAB::TCFv2::PublisherRestrictions');
use_ok('GDPR::IAB::TCFv2::RangeSection');
use_ok('GDPR::IAB::TCFv2::RangeConsent');
use_ok('GDPR::IAB::TCFv2');
}

Expand All @@ -21,7 +20,6 @@ require_ok 'GDPR::IAB::TCFv2::BitUtils';
require_ok 'GDPR::IAB::TCFv2::BitField';
require_ok('GDPR::IAB::TCFv2::PublisherRestrictions');
require_ok 'GDPR::IAB::TCFv2::RangeSection';
require_ok 'GDPR::IAB::TCFv2::RangeConsent';
require_ok 'GDPR::IAB::TCFv2';

subtest "check interfaces" => sub {
Expand All @@ -35,8 +33,6 @@ subtest "check interfaces" => sub {
can_ok 'GDPR::IAB::TCFv2::BitField', @methods;
can_ok 'GDPR::IAB::TCFv2::RangeSection', @methods;

can_ok 'GDPR::IAB::TCFv2::RangeConsent', qw<new contains all TO_JSON>;

can_ok 'GDPR::IAB::TCFv2::PublisherRestrictions',
qw<new check_publisher_restriction TO_JSON>;

Expand Down

0 comments on commit 9aa22a6

Please sign in to comment.