Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git

Reduces processing invocations

AuthorDave Jarvis <email>
Date2026-02-22 11:13:33 GMT-0800
Commit2f03b08a197661c5855223ae77ee712395ea7930
Parent970e690
git/DeltaDecoder.php
private const CHUNK_SIZE = 65536;
+ private const array COPY_INSTRUCTION_SIZES = [
+ 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ ];
+
public function apply( string $base, string $delta, int $cap ): string {
$pos = 0;
$offset = 0;
$yieldBuffer = '';
+ $yieldBufLen = 0;
$isStream = $base instanceof StreamReader;
foreach( $stream->stream( $handle ) as $data ) {
if( $offset > 0 ) {
$buffer = substr( $buffer, $offset );
$offset = 0;
}
- $buffer .= $data;
- $doneBuffer = false;
+ $buffer .= $data;
+ $bufLen = strlen( $buffer ); // loop invariant: buffer unchanged inside while
- while( !$doneBuffer ) {
- $len = strlen( $buffer ) - $offset;
+ while( $offset < $bufLen ) {
+ $len = $bufLen - $offset;
- if( $len === 0 ) {
- $doneBuffer = true;
- }
+ if( $state < 2 ) {
+ // Inline advanceToInstructions: scan past the variable-length source
+ // or target size integer (high-bit continuation bytes, then one
+ // terminating byte with bit-7 clear).
+ $pos = $offset;
+ $found = false;
- if( !$doneBuffer ) {
- if( $state < 2 ) {
- $this->advanceToInstructions(
- $buffer,
- $offset,
- $len,
- $state,
- $doneBuffer
- );
+ while( $pos < $bufLen ) {
+ if( !(ord( $buffer[$pos] ) & 128) ) {
+ $found = true;
+ $pos++;
+ break;
+ }
+
+ $pos++;
+ }
+
+ if( $found ) {
+ $offset = $pos;
+ $state++;
} else {
- yield from $this->processInstruction(
- $buffer,
- $offset,
- $len,
- $doneBuffer,
- $isStream,
- $base,
- $yieldBuffer
- );
+ break;
}
- }
- }
- }
+ } else {
+ $op = ord( $buffer[$offset] );
- if( $yieldBuffer !== '' ) {
- yield $yieldBuffer;
- }
- }
+ if( $op & 128 ) {
+ $need = self::COPY_INSTRUCTION_SIZES[$op & 0x7F];
- private function advanceToInstructions(
- string $buffer,
- int &$offset,
- int $len,
- int &$state,
- bool &$doneBuffer
- ): void {
- $pos = $offset;
- $found = false;
+ if( $len < 1 + $need ) {
+ break;
+ }
- while( !$found && $pos < $offset + $len ) {
- if( !(ord( $buffer[$pos] ) & 128) ) {
- $found = true;
- }
+ $off = 0;
+ $ln = 0;
+ $ptr = $offset + 1;
- $pos++;
- }
+ ($op & 0x01) ? $off |= ord( $buffer[$ptr++] ) : null;
+ ($op & 0x02) ? $off |= ord( $buffer[$ptr++] ) << 8 : null;
+ ($op & 0x04) ? $off |= ord( $buffer[$ptr++] ) << 16 : null;
+ ($op & 0x08) ? $off |= ord( $buffer[$ptr++] ) << 24 : null;
+ ($op & 0x10) ? $ln |= ord( $buffer[$ptr++] ) : null;
+ ($op & 0x20) ? $ln |= ord( $buffer[$ptr++] ) << 8 : null;
+ ($op & 0x40) ? $ln |= ord( $buffer[$ptr++] ) << 16 : null;
- if( $found ) {
- $offset = $pos;
- $state++;
- } else {
- $doneBuffer = true;
- }
- }
+ $ln = $ln === 0 ? 0x10000 : $ln;
- private function processInstruction(
- string $buffer,
- int &$offset,
- int $len,
- bool &$doneBuffer,
- bool $isStream,
- mixed $base,
- string &$yieldBuffer
- ): Generator {
- $op = ord( $buffer[$offset] );
+ if( $isStream ) {
+ $base->seek( $off );
+ $rem = $ln;
- if( $op & 128 ) {
- yield from $this->processCopyInstruction(
- $op,
- $buffer,
- $offset,
- $len,
- $doneBuffer,
- $isStream,
- $base,
- $yieldBuffer
- );
- } else {
- yield from $this->processInsertInstruction(
- $op,
- $buffer,
- $offset,
- $len,
- $doneBuffer,
- $yieldBuffer
- );
- }
- }
+ while( $rem > 0 ) {
+ $slc = $base->read( min( self::CHUNK_SIZE, $rem ) );
- private function processCopyInstruction(
- int $op,
- string $buffer,
- int &$offset,
- int $len,
- bool &$doneBuffer,
- bool $isStream,
- mixed $base,
- string &$yieldBuffer
- ): Generator {
- $need = $this->calculateCopyInstructionSize( $op );
+ if( $slc === '' ) {
+ $rem = 0;
+ } else {
+ $slcLen = strlen( $slc );
+ $yieldBuffer .= $slc;
+ $yieldBufLen += $slcLen;
+ $rem -= $slcLen;
- if( $len < 1 + $need ) {
- $doneBuffer = true;
- }
+ if( $yieldBufLen >= self::CHUNK_SIZE ) {
+ yield $yieldBuffer;
- if( !$doneBuffer ) {
- $off = 0;
- $ln = 0;
- $ptr = $offset + 1;
+ $yieldBuffer = '';
+ $yieldBufLen = 0;
+ }
+ }
+ }
+ } else {
+ $slc = substr( $base, $off, $ln );
+ $slcLen = strlen( $slc );
+ $yieldBuffer .= $slc;
+ $yieldBufLen += $slcLen;
- $this->parseCopyInstruction( $op, $buffer, $ptr, $off, $ln );
+ if( $yieldBufLen >= self::CHUNK_SIZE ) {
+ yield $yieldBuffer;
- if( $isStream ) {
- $base->seek( $off );
+ $yieldBuffer = '';
+ $yieldBufLen = 0;
+ }
+ }
- $rem = $ln;
+ $offset += 1 + $need;
+ } else {
+ $ln = $op & 127;
- while( $rem > 0 ) {
- $slc = $base->read( min( self::CHUNK_SIZE, $rem ) );
+ if( $len < 1 + $ln ) {
+ break;
+ }
- if( $slc === '' ) {
- $rem = 0;
- } else {
- $yieldBuffer .= $slc;
- $rem -= strlen( $slc );
+ $yieldBuffer .= substr( $buffer, $offset + 1, $ln );
+ $yieldBufLen += $ln;
+ $offset += 1 + $ln;
- if( strlen( $yieldBuffer ) >= self::CHUNK_SIZE ) {
+ if( $yieldBufLen >= self::CHUNK_SIZE ) {
yield $yieldBuffer;
$yieldBuffer = '';
+ $yieldBufLen = 0;
}
}
- }
- } else {
- $yieldBuffer .= substr( $base, $off, $ln );
-
- if( strlen( $yieldBuffer ) >= self::CHUNK_SIZE ) {
- yield $yieldBuffer;
-
- $yieldBuffer = '';
}
}
-
- $offset += 1 + $need;
- }
- }
-
- private function processInsertInstruction(
- int $op,
- string $buffer,
- int &$offset,
- int $len,
- bool &$doneBuffer,
- string &$yieldBuffer
- ): Generator {
- $ln = $op & 127;
-
- if( $len < 1 + $ln ) {
- $doneBuffer = true;
}
-
- if( !$doneBuffer ) {
- $yieldBuffer .= substr( $buffer, $offset + 1, $ln );
- $offset += 1 + $ln;
-
- if( strlen( $yieldBuffer ) >= self::CHUNK_SIZE ) {
- yield $yieldBuffer;
- $yieldBuffer = '';
- }
+ if( $yieldBuffer !== '' ) {
+ yield $yieldBuffer;
}
}
git/PackEntryReader.php
int $offset
): int {
+ if( isset( $this->cache[$offset] ) ) {
+ return \strlen( $this->cache[$offset] );
+ }
+
$cur = $stream->tell();
$cur = $stream->tell();
$baseOff = $offset - $neg;
- $size = $this->readSizeWithStream( $stream, $baseOff );
$baseSrc = '';
- if( $size <= self::MAX_BASE_RAM ) {
+ if( isset( $this->cache[$baseOff] ) ) {
+ $baseSrc = $this->cache[$baseOff];
+ } elseif( $this->readSizeWithStream( $stream, $baseOff ) <= self::MAX_BASE_RAM ) {
$baseSrc = $this->readWithStream(
$stream,
$rem = \strlen( $data ) - $pos;
- $rem > 0 ? $stream->seek( -$rem, SEEK_CUR ) : null;
+ if( $rem > 0 ) {
+ $stream->seek( -$rem, SEEK_CUR );
+ }
return $result;
Delta107 lines added, 153 lines removed, 46-line decrease