+our $lookup_path_col;
+our $on;
+
+sub __commit_begin {
+ warn "__commit_begin";
+ $lookup_path_col = undef;
+ $on = undef;
+}
+
+sub __commit_end {
+ warn "__commit_end";
+ $lookup_path_col = undef; # cleanup memory
+ $on = undef;
+}
+
+sub lookup {
+ warn "# lookup ",dump @_;
+ my ( $vals, $on_path, $on_col, $code, $stat_code ) = @_;
+ die "code is not sub{ ... } but ", dump $code unless ref $code eq 'CODE';
+
+ if ( ! exists $loaded->{$on_path} ) {
+ my @possible_paths = grep { /\Q$on_path\E/ } keys %$loaded;
+ die "more than one dataset available for '$on_path' ",dump @possible_paths if $#possible_paths > 0;
+ $on_path = shift @possible_paths;
+ warn "## fuzzy selected path $on_path";
+ }
+
+ my $items = $loaded->{$on_path}->{data}->{items} || die "no items for $on_path";
+
+ if ( ! exists $lookup_path_col->{$on_path}->{$on_col} ) {
+ warn "create lookup_path_col $on_path $on_col";
+ foreach my $i ( 0 .. $#$items ) {
+ my $item = $items->[$i];
+ if ( exists $item->{$on_col} ) {
+ if ( ref $item->{$on_col} eq 'ARRAY' ) {
+ foreach my $v ( @{ $item->{$on_col} } ) {
+ push @{ $lookup_path_col->{$on_path}->{$on_col}->{$v} }, $i;
+ }
+ } elsif ( ! ref $item->{$on_col} ) { # scalar
+ my $v = $item->{$on_col};
+ push @{ $lookup_path_col->{$on_path}->{$on_col}->{$v} }, $i;
+ } else {
+ die "unknown type of ",dump $item->{$on_col};
+ }
+ }
+ }
+ warn "XXX ",dump $lookup_path_col->{$on_path}->{$on_col} if $ENV{DEBUG};
+ }
+
+ my $stat;
+ $stat = Statistics::Descriptive::Full->new() if $stat_code;
+
+ foreach my $v ( ref $vals eq 'ARRAY' ? @$vals : ( $vals ) ) {
+ foreach my $i ( @{ $lookup_path_col->{$on_path}->{$on_col}->{$v} } ) {
+ $on = $items->[$i];
+ warn "XXX lookup code $v $i ",dump $on if $ENV{DEBUG};
+ $code->($stat);
+ }
+ $stat_code->( $stat ) if $stat_code;
+ }
+}
+