Skip to content

Commit bb6be71

Browse files
committed
Change token map lookup to avoid creating associative array
1 parent e8b2cff commit bb6be71

2 files changed

Lines changed: 665 additions & 646 deletions

File tree

src/wp-includes/class-wp-token-map.php

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class WP_Token_Map {
9898
*/
9999
private $large_words = array();
100100

101+
private $groups = '';
102+
101103
/**
102104
* Stores an optimized row of short words, where every entry is
103105
* `$this->key_size + 1` bytes long and zero-extended.
@@ -195,16 +197,23 @@ public static function from_array( $mappings, $key_length = 2 ) {
195197
$map->small_mappings[] = $mappings[ $word ];
196198
}
197199

198-
foreach ( $groups as $group => $group_words ) {
200+
$group_keys = array_keys( $groups );
201+
sort( $group_keys );
202+
203+
foreach ( $group_keys as $group ) {
204+
$map->groups .= "{$group}\x00";
205+
199206
$group_string = '';
200207

201-
foreach ( $group_words as $group_word ) {
208+
foreach ( $groups[ $group ] as $group_word ) {
202209
list( $word, $mapping ) = $group_word;
203210

204-
$group_string .= pack( 'C', strlen( $word ) ) . $word . pack( 'C', strlen( $mapping ) ) . $mapping;
211+
$word_length = pack( 'C', strlen( $word ) );
212+
$mapping_length = pack( 'C', strlen( $mapping ) );
213+
$group_string .= "{$word_length}{$word}{$mapping_length}{$mapping}";
205214
}
206215

207-
$map->large_words[ $group ] = $group_string;
216+
$map->large_words[] = $group_string;
208217
}
209218

210219
return $map;
@@ -226,10 +235,11 @@ public static function from_array( $mappings, $key_length = 2 ) {
226235
*
227236
* @return WP_Token_Map Map with precomputed data loaded.
228237
*/
229-
public static function from_precomputed_table( $key_length, $large_words, $small_words, $small_mappings ) {
238+
public static function from_precomputed_table( $key_length, $groups, $large_words, $small_words, $small_mappings ) {
230239
$map = new WP_Token_Map();
231240

232241
$map->key_length = $key_length;
242+
$map->groups = $groups;
233243
$map->large_words = $large_words;
234244
$map->small_words = $small_words;
235245
$map->small_mappings = $small_mappings;
@@ -261,11 +271,11 @@ public function contains( $word ) {
261271
}
262272

263273
$group_key = substr( $word, 0, $this->key_length );
264-
if ( ! isset( $this->large_words[ $group_key ] ) ) {
274+
$group_at = strpos( $this->groups, $group_key );
275+
if ( false === $group_at ) {
265276
return false;
266277
}
267-
268-
$group = $this->large_words[ $group_key ];
278+
$group = $this->large_words[ $group_at / ( $this->key_length + 1 ) ];
269279
$group_length = strlen( $group );
270280
$slug = substr( $word, $this->key_length );
271281
$length = strlen( $slug );
@@ -336,7 +346,8 @@ public function read_token( $text, $offset = 0, &$skip_bytes = null ) {
336346
if ( $text_length > $this->key_length ) {
337347
$group_key = substr( $text, $offset, $this->key_length );
338348

339-
if ( ! isset( $this->large_words[ $group_key ] ) ) {
349+
$group_at = strpos( $this->groups, $group_key );
350+
if ( false === $group_at ) {
340351
// Perhaps a short word then.
341352
$small_text = str_pad( substr( $text, $offset, $this->key_length ), $this->key_length + 1, "\x00", STR_PAD_RIGHT );
342353
$at = strpos( $this->small_words, $small_text );
@@ -349,7 +360,7 @@ public function read_token( $text, $offset = 0, &$skip_bytes = null ) {
349360
return $this->small_mappings[ $at / ( $this->key_length + 1 ) ];
350361
}
351362

352-
$group = $this->large_words[ $group_key ];
363+
$group = $this->large_words[ $group_at / ( $this->key_length + 1 ) ];
353364
$group_length = strlen( $group );
354365
$at = 0;
355366
while ( $at < $group_length ) {
@@ -408,7 +419,8 @@ public function to_array() {
408419
$at += $this->key_length + 1;
409420
}
410421

411-
foreach ( $this->large_words as $prefix => $group ) {
422+
foreach ( $this->large_words as $index => $group ) {
423+
$prefix = substr( $this->groups, $index * ( $this->key_length + 1 ), 2 );
412424
$group_length = strlen( $group );
413425
$at = 0;
414426
while ( $at < $group_length ) {
@@ -457,15 +469,21 @@ public function precomputed_php_source_table( $indent = "\t" ) {
457469

458470
$output = self::class . "::from_precomputed_table(\n";
459471
$output .= "{$i1}{$this->key_length},\n";
472+
473+
$group_line = str_replace( "\x00", "\\x00", $this->groups );
474+
$output .= "{$i1}\"{$group_line}\",\n";
475+
460476
$output .= "{$i1}array(\n";
461477

462-
$prefixes = array_keys( $this->large_words );
463-
sort( $prefixes );
464-
foreach ( $prefixes as $prefix ) {
465-
$group = $this->large_words[ $prefix ];
478+
$prefixes = explode( "\x00", $this->groups );
479+
foreach ( $prefixes as $index => $prefix ) {
480+
if ( '' === $prefix ) {
481+
break;
482+
}
483+
$group = $this->large_words[ $index ];
466484
$group_length = strlen( $group );
467485
$comment_line = "{$i2}//";
468-
$data_line = "{$i2}'{$prefix}' => \"";
486+
$data_line = "{$i2}\"";
469487
$at = 0;
470488
while ( $at < $group_length ) {
471489
$token_length = unpack( 'C', $group[ $at++ ] )[1];

0 commit comments

Comments
 (0)