Skip to content

Commit 1674332

Browse files
committed
Add toFixedArray and toGenerator methods
1 parent ad8cf5b commit 1674332

5 files changed

Lines changed: 114 additions & 5 deletions

File tree

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ You can still iterate over it as if it was a normal array.
1414

1515
One typical use case would be to load a lot of datasets from a database at once. (There are reasons to prefer this over running multiple queries.) See *Usage* below for an example for this use case using this library.
1616

17+
In general, you might want to try the following PHP-builtin solutions first:
18+
19+
- [SplFixedArray](https://www.php.net/manual/class.splfixedarray.php): By being of fixed length, this saves some memory compared to traditional `array`s. It behaves pretty much like `array`s do. Although the savings are not that huge compared to other solutions, it is probably the easiest to adopt.
20+
- [Generator](https://www.php.net/manual/language.generators.php): Instead of returning an `array` all at once, this allows to return one item after the other. Thereby a "consumer" is able to process one item after the other accordingly. One can also terminate the "generation" of further items. One of the downsides is, that a Generator can only be iterated over once. The memory consumption can be as good as constant, but this approach is quite different and therefore rather hard to adopt and not appropriate in every scenario.
21+
22+
It should be noted, that a `LargeArrayBuffer` can be converted to both of these using `toFixedArray()` and `toGenerator()` respectively.
23+
1724
## Install
1825

1926
Note: This library requires PHP 8.0+!

src/ArrayBuffer.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,36 @@ public function toArray(): array {
112112
return $this->array;
113113
}
114114
}
115+
116+
/**
117+
* @psalm-return \SplFixedArray<E>
118+
*/
119+
public function toFixedArray(): \SplFixedArray {
120+
if($this->buffer->count() > 0){
121+
return $this->buffer->toFixedArray();
122+
} else {
123+
$res = new \SplFixedArray(count($this->array));
124+
foreach($this->array as $idx => $item){
125+
$res[$idx] = $item;
126+
}
127+
return $res;
128+
}
129+
}
130+
131+
/**
132+
* @return \Generator send something other than null to terminate
133+
* @psalm-return \Generator<int, E, mixed, void>
134+
*/
135+
public function toGenerator(): \Generator {
136+
if($this->buffer->count() > 0){
137+
yield from $this->buffer->toGenerator();
138+
} else {
139+
foreach($this->array as $item){
140+
$cmd = yield $item;
141+
if($cmd !== null){
142+
break;
143+
}
144+
}
145+
}
146+
}
115147
}

src/ArrayBufferInterface.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,15 @@ public function push(mixed $item): void;
2020
* @psalm-return list<E>
2121
*/
2222
public function toArray(): array;
23+
24+
/**
25+
* @psalm-return \SplFixedArray<E>
26+
*/
27+
public function toFixedArray(): \SplFixedArray;
28+
29+
/**
30+
* @return \Generator send something other than null to terminate
31+
* @psalm-return \Generator<int, E, mixed, void>
32+
*/
33+
public function toGenerator(): \Generator;
2334
}

src/LargeArrayBuffer.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,30 @@ public function toArray(): array {
236236
}
237237
return $res;
238238
}
239+
240+
/**
241+
* @psalm-return \SplFixedArray<E>
242+
*/
243+
public function toFixedArray(): \SplFixedArray {
244+
$res = new \SplFixedArray($this->count);
245+
foreach($this as $idx => $item){
246+
$res[$idx] = $item;
247+
}
248+
return $res;
249+
}
250+
251+
/**
252+
* @return \Generator send something other than null to terminate
253+
* @psalm-return \Generator<int, E, mixed, void>
254+
*/
255+
public function toGenerator(): \Generator {
256+
foreach($this as $item){
257+
$cmd = yield $item;
258+
if($cmd !== null){
259+
break;
260+
}
261+
}
262+
}
239263

240264
public function __destruct() {
241265
/**

test/LargeArrayBufferTest.php

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,7 @@ public function testLoop(): void {
9696
}
9797

9898
public function testToJSON(): void {
99-
$o = new \stdClass();
100-
$o->foo = 'hello world!'.PHP_EOL;
101-
$o->bar = new \DateTimeImmutable();
102-
$o->a = ['test', 123];
103-
$o->str = 'hello world!\\n';
99+
$o = $this->getObject();
104100

105101
$buf = new LargeArrayBuffer();
106102
$buf->push($o);
@@ -112,4 +108,43 @@ public function testToJSON(): void {
112108
fclose($stream);
113109
$this->assertEquals(json_encode([$o, $o], JSON_THROW_ON_ERROR), $json);
114110
}
111+
112+
public function provideItems(): array {
113+
return [
114+
[['hello world!', 'just another string']]
115+
];
116+
}
117+
118+
/**
119+
* @dataProvider provideItems
120+
*/
121+
public function testToArray(array $items): void {
122+
$buf = new LargeArrayBuffer();
123+
foreach($items as $item){
124+
$buf->push($item);
125+
}
126+
$this->assertSame($items, $buf->toArray());
127+
}
128+
129+
/**
130+
* @dataProvider provideItems
131+
*/
132+
public function testToFixedArray(array $items): void {
133+
$buf = new LargeArrayBuffer();
134+
foreach($items as $item){
135+
$buf->push($item);
136+
}
137+
$this->assertSame($items, $buf->toFixedArray()->toArray());
138+
}
139+
140+
/**
141+
* @dataProvider provideItems
142+
*/
143+
public function testToGenerator(array $items): void {
144+
$buf = new LargeArrayBuffer();
145+
foreach($items as $item){
146+
$buf->push($item);
147+
}
148+
$this->assertSame($items, iterator_to_array($buf->toGenerator()));
149+
}
115150
}

0 commit comments

Comments
 (0)