Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

hash table support #1

Closed
wants to merge 1 commit into from

2 participants

@Elbandi

This is the patch for this feature request:
https://pear.php.net/bugs/bug.php?id=18562

Elbandi

@CloCkWeRX
Owner

Thanks! I'd missed this pull request, sorry for the delay.

@CloCkWeRX

Can you fix the signature to be _is_prime($candiate) with no space?
Also, any chance of docblocks?

@CloCkWeRX

Can you avoid inline control structures? (add braces)

@CloCkWeRX

As above re inline structures

@CloCkWeRX

Inline structures again

@CloCkWeRX
Owner

Hmm odd: "Your merge target has changed since we cached the merge commit - try the merge again"

@CloCkWeRX CloCkWeRX closed this
@CloCkWeRX
Owner

I cherry picked all of your commits, so this is now closeable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 2, 2012
  1. @Elbandi

    save hash table to MO

    Elbandi authored
This page is out of date. Refresh to see the latest.
Showing with 77 additions and 1 deletion.
  1. +77 −1 Gettext/MO.php
View
78 Gettext/MO.php
@@ -252,6 +252,49 @@ function load($file = null)
return true;
}
+ private function _hashpjw($str_param)
+ {
+ $hval = 0;
+ for($i = 0; $i<strlen($str_param); $i++)
+ {
+ $hval <<= 4;
+ $hval += ord($str_param[$i]);
+ $g = $hval & 0xf << 28; // $HASHWORDBITS - 4
+ if ($g != 0) {
+ $hval ^= $g >> 24; // $HASHWORDBITS - 8
+ $hval ^= $g;
+ }
+ }
+ return $hval;
+ }
+
+ private function _is_prime ($candidate)
+ {
+ /* No even number and none less than 10 will be passed here. */
+ $divn = 3;
+ $sq = $divn * $divn;
+
+ while ($sq < $candidate && $candidate % $divn != 0)
+ {
+ ++$divn;
+ $sq += 4 * $divn;
+ ++$divn;
+ }
+
+ return $candidate % $divn != 0;
+ }
+
+ private function _next_prime($seed)
+ {
+ /* Make it definitely odd. */
+ $seed |= 1;
+
+ while (!self::_is_prime ($seed))
+ $seed += 2;
+
+ return $seed;
+ }
+
/**
* Save MO file
*
@@ -290,6 +333,11 @@ function save($file = null)
// write count of strings
$this->_writeInt($count);
+ $hash_tab_size = self::_next_prime (($count * 4) / 3);
+ /* Ensure M > 2. */
+ if ($hash_tab_size <= 2)
+ $hash_tab_size = 3;
+
$offset = 28;
// write offset of orig. strings hash table
$this->_writeInt($offset);
@@ -299,12 +347,14 @@ function save($file = null)
$this->_writeInt($offset);
// write size of hash table (we currently ommit the hash table)
- $this->_writeInt(0);
+ $this->_writeInt($hash_tab_size); // orig: 0
$offset += ($count * 8);
// write offset of hash table
$this->_writeInt($offset);
+ $offset += ($hash_tab_size * 4);
+
// unshift meta info
if ($meta) {
$meta = '';
@@ -316,6 +366,27 @@ function save($file = null)
$strings = $this->strings;
}
+ $hash_tab = array();
+ $j = 0;
+ foreach ($strings as $key => $value)
+ {
+ $hash_val = self::_hashpjw($key);
+ $idx = $hash_val % $hash_tab_size;
+ if (!empty($hash_tab[$idx]))
+ {
+ $incr = 1 + ($hash_val % ($hash_tab_size - 2));
+ do
+ if ($idx >= $hash_tab_size - $incr)
+ $idx -= $hash_tab_size - $incr;
+ else
+ $idx += $incr;
+ while (!empty($hash_tab[$idx]));
+ }
+
+ $hash_tab[$idx] = $j + 1;
+ $j++;
+ }
+
// write offsets for original strings
foreach (array_keys($strings) as $o) {
$len = strlen($o);
@@ -332,6 +403,11 @@ function save($file = null)
$offset += $len + 1;
}
+ for ($j = 0; $j < $hash_tab_size; $j++) {
+ if (empty($hash_tab[$j])) $this->_writeInt(0);
+ else $this->_writeInt($hash_tab[$j]);
+ }
+
// write original strings
foreach (array_keys($strings) as $o) {
$this->_writeStr($o);
Something went wrong with that request. Please try again.