Skip to content

Dynamic BitSet size, Getter Setter for BitSet #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2015
Merged

Dynamic BitSet size, Getter Setter for BitSet #51

merged 1 commit into from
Jun 3, 2015

Conversation

TuxCoder
Copy link
Contributor

@TuxCoder TuxCoder commented Jun 2, 2015

new pull request for #50

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 2, 2015

when i think about little an big endian, have we not to use little endian?
https://en.wikipedia.org/wiki/Endianness#Mapping_multi-byte_binary_values_to_memory

so if a 64bit machine exports data the 32bit machine can't handle the big endian but the little endian.

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 2, 2015

workaround for php<5.6.3 because pack don't suport 64bit numbers.
changed to little endian. now hex2bin($bitstring) for enum65:
64bit: 02000000000000800100000000000000
32bit: 020000000000008001000000

$this->integerSize = 4*8;
}else {
$this->integerSize = PHP_INT_SIZE*8;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$this->integerSize = PHP_INT_SIZE * 8; should work on all versions. The issue before was calculating the value of integerSize on compile time which wasn't supported before 5.6.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is that php pack only support 32bit before 5.6.3
https://php.net/manual/en/function.pack.php

@marc-mabe
Copy link
Owner

when i think about little an big endian, have we not to use little endian?
https://en.wikipedia.org/wiki/Endianness#Mapping_multi-byte_binary_values_to_memory

so if a 64bit machine exports data the 32bit machine can't handle the big endian but the little endian.

It doesn't matter as you already known if it's a 64bit or a 32bit machine with PHP_INT_SIZE.

I would like to make it simple possible to share this binary bitset with others like with SQL and there it goes back to write integers as hex strings in big endian order:

// SQL
$hex = $db->query('SELECT HEX(`col`) FROM t')->fetchColumn(0);
$enumSet->setBitset(hex2bin($hex));

@marc-mabe
Copy link
Owner

We can simply split the bitset in 32bit chunks so there is no difference for 32bit vs. 64bit machines. This should simplify the code a little or even better split it into bytes so in fact it doesn't be splitted because we can access the correct byte the same way as array of bytes.

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 2, 2015

It doesn't matter as you already known if it's a 64bit or a 32bit machine with PHP_INT_SIZE.
my idea behind that is that it doesn't matter what system you have, you get always the same string.

I interate the bitset reverse and so I have both.
Haven't thought about the database commands...

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 2, 2015

binary strings now:
64bit: 0x00000000000000018000000000000002
32bit: 0x000000018000000000000002

@marc-mabe
Copy link
Owner

This is a working solution using string offset and making $this->integerSize and pack obsolete:

    /**
     * Get the binary bitset
     * @return string Returns the binary bitset in big-endian order
     */
    public function getBitset() {
        return strrev($this->bitset);
    }

    /**
     * Set the bitset.
     * NOTE: It resets the current position of the iterator
     * @param string $bitset The binary bitset in big-endian order
     * @return void
     */
    public function setBitset($bitset) {
        if (!is_string($bitset)) {
            throw new \InvalidArgumentException("bitset must be a string");
        }

        $bitset = strrev($bitset);
        $size   = ceil($this->ordinalMax / 8);
        $sizeIn = strlen($bitset);

        if ($sizeIn < $size) {
            //add "\0" if the given bitset is not long enough
            $bitset .= str_repeat("\0", $size - $sizeIn);
        } elseif ($sizeIn > $size) {
            $bitset = substr($bitset, 0, $size);
        }

        $this->bitset = $bitset;

        $this->rewind();
    }

    /**
     * get a bit at the given ordinal
     * @param $ordinal    number of bit to get
     * @return boolean
     */
    private function getBit($ordinal) {
        return (ord($this->bitset[(int)($ordinal/8)]) & 1 << ($ordinal % 8))!=0;
    }

    /**
     * set a bit at the given ordinal
     * @param $ordinal  int number of bit to manipulate
     * @return void
     */
    private function setBit($ordinal) {
        $byte = (int)($ordinal/8);
        $this->bitset[$byte] = $this->bitset[$byte] | chr(1 << ($ordinal % 8));
    }

    /**
     * reset a bit at the given ordinal
     * @param $ordinal  int number of bit to set to false
     * @return void
     */
    private function unsetBit($ordinal) {
        $byte = (int)($ordinal/8);
        $this->bitset[$byte] = $this->bitset[$byte] & chr(~(1 << $ordinal % 8));
    }

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 2, 2015

Much better, why we don't do this in the beginning ^^.

bin2hex($bitstring) look now like: 0x018000000000000002

should now all do what it should.

}

//init the bitset with zeros
$this->setBitset("");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Micro optimization: $this->bitset = str_repeat("\0", ceil($this->ordinalMax / 8));

@marc-mabe
Copy link
Owner

Looks great! - only some very minor notes :)

PS: Can you double check your coding style please PSR-2 ... mostly missing whitespace between operands like $this->ordinalMax/8 -> $this->ordinalMax / 8 and the starting { on methods should be on a new line.

Thanks

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 3, 2015

Should now be good.

I say also thanks learned a lot about how to program nice code.

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 3, 2015

At first i oversaw the code comments

@marc-mabe
Copy link
Owner

Thanks!

Please rebase to merge all your commits of this PR into a single one so I can merge into master.

@marc-mabe marc-mabe added this to the 2.1.0 milestone Jun 3, 2015
@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 3, 2015

Can you help me with that, I'm not such familiar with the deeper git commands.

@TuxCoder
Copy link
Contributor Author

TuxCoder commented Jun 3, 2015

@marc-mabe
Copy link
Owner

thanks all want - thanks!

marc-mabe added a commit that referenced this pull request Jun 3, 2015
Dynamic BitSet size, Getter Setter for BitSet
@marc-mabe marc-mabe merged commit af186da into marc-mabe:master Jun 3, 2015
@TuxCoder TuxCoder deleted the master-bitset branch June 3, 2015 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants