Skip to content

Commit

Permalink
Merge branch 'main' of github.com:neo4j-php/neo4j-php-client into kit…
Browse files Browse the repository at this point in the history
…labs-cn-main
  • Loading branch information
transistive committed Mar 28, 2024
2 parents 3049148 + f8748af commit 5a62778
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 27 deletions.
19 changes: 10 additions & 9 deletions src/Types/AbstractCypherSequence.php
Original file line number Diff line number Diff line change
Expand Up @@ -446,15 +446,16 @@ public function current(): mixed

public function valid(): bool
{
return $this->currentPosition < $this->generatorPosition || $this->getGenerator()->valid();
return $this->currentPosition < $this->generatorPosition || array_key_exists($this->currentPosition, $this->keyCache) || $this->getGenerator()->valid();
}

public function rewind(): void
{
$this->currentPosition = max(
$this->currentPosition - $this->cacheLimit - 1,
0
);
if ($this->currentPosition > $this->cacheLimit) {
throw new BadMethodCallException('Cannot rewind cursor: limit exceeded. In order to increase the amount of prefetched (and consequently cached) rows, increase the fetch limit in the session configuration.');
}

$this->currentPosition = 0;
}

public function next(): void
Expand Down Expand Up @@ -489,7 +490,7 @@ public function key(): mixed
*/
protected function cacheKey()
{
return $this->keyCache[$this->currentPosition % max($this->cacheLimit - 1, 1)];
return $this->keyCache[$this->currentPosition % max($this->cacheLimit, 1)];
}

/**
Expand Down Expand Up @@ -519,9 +520,9 @@ private function setupCache(): void
{
$generator = $this->getGenerator();

if (count($this->cache) % $this->cacheLimit === 0) {
$this->cache = [];
$this->keyCache = [];
if (count($this->cache) !== 0 && count($this->cache) % ($this->cacheLimit + 1) === 0) {
$this->cache = [array_key_last($this->cache) => $this->cache[array_key_last($this->cache)]];
$this->keyCache = [$this->keyCache[array_key_last($this->keyCache)]];
}

if ($this->cache === [] && $generator->valid()) {
Expand Down
29 changes: 11 additions & 18 deletions src/Types/ArrayList.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
namespace Laudis\Neo4j\Types;

use AppendIterator;

use function array_values;

use ArrayIterator;
use Generator;

Expand Down Expand Up @@ -45,22 +42,18 @@ class ArrayList extends AbstractCypherSequence
public function __construct($iterable = [])
{
if (is_array($iterable)) {
/** @var array<array-key, TValue> $iterable */
$this->keyCache = count($iterable) === 0 ? [] : range(0, count($iterable) - 1);
$this->cache = array_values($iterable);
$this->generator = new ArrayIterator([]);
$this->generatorPosition = count($this->keyCache);
} else {
$this->generator = static function () use ($iterable): Generator {
$i = 0;
/** @var Generator<mixed, TValue> $it */
$it = is_callable($iterable) ? $iterable() : $iterable;
foreach ($it as $value) {
yield $i => $value;
++$i;
}
};
$iterable = new ArrayIterator($iterable);
}

$this->generator = static function () use ($iterable): Generator {
$i = 0;
/** @var Generator<mixed, TValue> $it */
$it = is_callable($iterable) ? $iterable() : $iterable;
foreach ($it as $value) {
yield $i => $value;
++$i;
}
};
}

/**
Expand Down
36 changes: 36 additions & 0 deletions tests/Unit/CypherListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,42 @@ public function testSlice(): void
self::assertEquals(array_sum(range(5, 7)), $sumAfter);
}

public function testRewindValid(): void
{
$list = $this->list->withCacheLimit(4);

$x = iterator_to_array($list);
$y = iterator_to_array($list);

$this->assertEquals(['A', 'B', 'C'], $x);
$this->assertEquals(['A', 'B', 'C'], $y);
}

public function testRewindValidExact(): void
{
$list = $this->list->withCacheLimit(3);

$x = iterator_to_array($list);
$y = iterator_to_array($list);

$this->assertEquals(['A', 'B', 'C'], $x);
$this->assertEquals(['A', 'B', 'C'], $y);
}

public function testRewindInValid(): void
{
$list = $this->list->withCacheLimit(2);

$x = iterator_to_array($list);

$this->assertEquals(['A', 'B', 'C'], $x);

$this->expectException(BadMethodCallException::class);
$this->expectExceptionMessage('Cannot rewind cursor: limit exceeded. In order to increase the amount of prefetched (and consequently cached) rows, increase the fetch limit in the session configuration.');

iterator_to_array($list);
}

/**
* @return Generator<int, int>
*/
Expand Down

0 comments on commit 5a62778

Please sign in to comment.