NAME

Bit::Set::DB::OO - Perl Object Oriented (OO) interface for bitset containers from the Bit C library

VERSION

version 0.13

SYNOPSIS

use Bit::Set::DB::OO;         ## OO interface to BitDB C library
use Bit::Set::DB qw(:all);    ## Procedural interface to BitDB C library 
                              ## (but do you need this if you use OO?)

# Create a new bitset database
my $bitdb = Bit::Set::DB->new(1024, 10); # 10 bitsets of length 1024 bits each

# Get a bitset from the database
my $bitset = $bitdb->get_from(0); # Get the first bitset

# Perform set operations
my $other_bitset = $bitdb->get_from(1); # Get the second bitset
my $union_bitset = $bitset->union($other_bitset);

# Count set bits in the union
my $count = $union_bitset->count();

DESCRIPTION

This module provides an OO Perl interface to the C library Bit, for creating and manipulating containers of bitsets (BitDB), leveraging multithreadedand hardware accelerated (e.g. GPU) versions of container operations e.g. forming the population count of the intersection of two containers of bitsets.

This is a pure OO interface using Perl's XS mechanism to interface with the Bit library.

GPU offloading is disabled if you set up the NOGPU environment variable.

METHODS

The methods provided by this module correspond to the functions provided by the procedural interface in Bit::Set::DB. The method names correspond to the function names without the BitDB_ prefix. Note that the methods are created in the Bit::Set::DB namespace.

Creation

Bit::Set::DB->new(length, num_of_bitsets)

Creates a new bitset container for num_of_bitsets bitsets, each of length.

Bit::Set::DB->load(length, num_of_bitsets, buffer address - numeric)

Creates a new bitset container for num_of_bitsets bitsets, each of length, from an external buffer. The buffer address should point to a memory region large enough to hold all bitsets.

Properties

$container->length(set)

Returns the length of bitsets in the container.

$container->nelem()

Returns the number of bitsets in the container.

$container->count_at(index)

Returns the population count of the bitset at the given index.

$container->count()

Returns a pointer to an array of population counts for all bitsets in the container.

Manipulation

$container->get_from(index)

Returns a bitset from the container at the given index.

$container->put_at(index, bitset)

Puts a bitset into the container at the given index.

$container->extract_from(index, buffer)

Extracts a bitset from the container at index into a buffer.

$container->replace_at(index, buffer)

Replaces a bitset in the container at index with the contents of a buffer.

$container->clear()

Clears all bitsets in the container.

$container->clear_at(index)

Clears the bitset at a given index in the container.

Set Operation Counts

These functions perform set operations between two bitset containers. The opts parameter is an object of type Bit::Set::DB::SETOP_COUNT_OPTS.

Example for opts:

my $opts = Bit::Set::DB::SETOP_COUNT_OPTS->new(
    num_cpu_threads => 4,
    device_id       => 0,
    # ... other flags
);

Perform the respective set operation count on the CPU:

$container->inter_count_cpu(container2, opts,...)
$container->union_count_cpu(container2, opts,...)
$container->diff_count_cpu(container2, opts,...)
$container->minus_count_cpu(container2, opts,...)

Perform the respective set operation count on the GPU:

$container->inter_count_gpu(container2, opts,...)
$container->union_count_gpu(container2, opts,...)
$container->diff_count_gpu(container2, opts,...)
$container->minus_count_gpu(container2, opts,...)

The optional ... argument is used to determine the type of the returned counts buffer:

If omitted,undef or zero the function returns a reference to an array of integers containing the counts.
If the optional parameter argument value is set to the integer 1, the function will return a pointer to a buffer containing the counts as an array of integers.

This pointer can be used with the Task::MemManager module to provide a memory leak-free way to manage its lifetime.

$container->inter_count_store_cpu(container2, buffer, opts)
$container->union_count_store_cpu(container2, buffer, opts)
$container->diff_count_store_cpu(container2, buffer, opts)
$container->minus_count_store_cpu(container2, buffer, opts)

Perform the respective set operation count on the GPU and store results in buffer:

$container->inter_count_store_gpu(container2, buffer, opts)
$container->union_count_store_gpu(container2, buffer, opts)
$container->diff_count_store_gpu(container2, buffer, opts)
$container->minus_count_store_gpu(container2, buffer, opts)

EXAMPLES

Examples of the use of the Bit::Set::DB::OO module that illustrates the use of the OO interface for bitset containers. The parent module Bit::Set::DB provides further procedural examples of the use of bitset containers.

Example 1: Creating and initializing containers

In this example, we will create two Perl arrays of Bit::Set and then load them to Bit::Set::DB containers using the OO interface.

use strict;
use warnings;
use Bit::Set::OO;
use Bit::Set::DB::OO;

my $size            = 1024;
my $num_of_bits     = 3;
my $num_of_ref_bits = 5;

my @bits;
my @bitsets;

# Initializing and setting the values of the bitsets
for my $i ( 0 .. $num_of_bits - 1 ) {
    $bits[$i] = Bit::Set->new($size);
    my $end = int( $size / 2 ) + $i;
    $end = ( $end > $size - 1 ) ? $size - 1 : $end;
     $bits[$i]->set( int( $size / 2 ), $end );
}
for my $i ( 0 .. $num_of_ref_bits - 1 ) {
    $bitsets[$i] = Bit::Set->new($size);
    my $end = int( $size / 2 ) + $i;
    $end = ( $end > $size - 1 ) ? $size - 1 : $end;
    $bitsets[$i]->set( int( $size / 2 ), $end );
}
$bits[0]->set(    int( $size / 2 ) - 1, int( $size / 2 ) + 5 );
$bitsets[0]->set( int( $size / 2 ),     int( $size / 2 ) + 5 );

# Create BitDB containers
my $db1 = Bit::Set::DB->new( $size, $num_of_bits );
my $DB = Bit::Set::DB->new( $size, $num_of_ref_bits );

# Now put the bitsets into the containers
for my $i ( 0 .. $num_of_bits - 1 ) {
    $db1->put_at( $i, $bits[$i] );
}
for my $i ( 0 .. $num_of_ref_bits - 1 ) {
    $DB->put_at( $i, $bitsets[$i] );
}

say $_ for do{my $x = $db1->count; $x->@*};
Example 2: Obtaining the counts of bitset operations using containers and OO

This example continues Example 1 by performing the intersection count in two different ways: 1) iterating over the Perl arrays of bitsets and 2) using the BitDB containers directly. A major benefit of these containerized operations is that they can leverage multi-threading in the CPU and hardware acceleration in GPUs (and TPUs in the near future).

use Test::More;
use FFI::Platypus::Buffer;
use FFI::Platypus::Memory;
use Config;                     # to get the size of int

my $num_threads = 4;
my $opts        = Bit::Set::DB::SETOP_COUNT_OPTS->new(
    num_cpu_threads     => $num_threads,
    device_id           => 0,
    upd_1st_operand     => 0,
    upd_2nd_operand     => 0,
    release_1st_operand => 0,
    release_2nd_operand => 0,
    release_counts      => 0
);
my $nelem = $db1->nelem() * $DB->nelem();

# Method 1: Using Perl arrays of Bit::Set
my @cpu_set_counts;
for my $i ( 0 .. $num_of_bits - 1 ) {
    for my $j ( 0 .. $num_of_ref_bits - 1 ) {
        my $count = $bits[$i]->inter_count( $bitsets[$j] );
        push @cpu_set_counts, $count;
    }
}

# Method 2: Using Bit::Set::DB containers
my $cpu_DB_counts_ptr = $db1->inter_count_cpu( $DB, $opts );
my $test_result = 1;
for my $k ( 0 .. $nelem - 1 ) {
    if ( $cpu_DB_counts_ptr->[$k] != $cpu_set_counts[$k] ) {
        $test_result = 0;
        last;
    }
}
ok( $test_result, "BitDB CPU intersection counts match Bit::Set counts" );

SEE ALSO

Alien::Bit

This distribution provides the library Bit so that it can be used by other Perl distributions that are on CPAN. It will download Bit from Github and will build the (static and dynamic) versions of the library for use by other Perl modules.

benchmarking-bits

A collection of benchmarking scripts for various bitset libraries in C and Perl.

Bit

Bit is a high-performance, uncompressed bitset implementation in C, optimized for modern architectures. The library provides an efficient way to create, manipulate, and query bitsets with a focus on performance and memory alignment. The API and the interface is largely based on David Hanson's Bit_T library discussed in Chapter 13 of "C Interfaces and Implementations", Addison-Wesley ISBN 0-201-49841-3 extended to incorporate additional operations (such as counts on unions/differences/intersections of sets), fast population counts using the libpocnt library and GPU operations for packed containers of (collections) of Bit(sets).

Bit::Set

Bit::Set is a Perl module that provides a high-level procedural interface for working with bitsets. It is built on top of the Bit library and offers a more user-friendly Perl API for common bitset operations.

Bit::Set::OO

Object Oriented interface to the Bit::Set module.

Bit::Set::DB

Procedural interface to the containerized operations of the Bit library.

Bit::Vector

Efficient bit vector, set of integers and "big int" math library

Lucy::Object::BitVector

Bit vector implementation used in the Lucy search engine library.

TO DO

  • Add more examples.

  • Add more tests.

    =item* Switch to XS for better performance.

AUTHOR

Christos Argyropoulos and Joe Schaefer after v0.11. Christos Argyropoulos with asistance from Github Copilot (Claude Sonnet 4) up to v0.10.

COPYRIGHT AND LICENSE

For versions after v0.10, the distribution as a whole is copyright (c) 2025 Joe Schaefer and Christos Argyropoulos. This software up to and including v0.10 is copyright (c) 2025 Christos Argyropoulos.

This software is released under the MIT license.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 216:

You forgot a '=back' before '=head1'