Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/RunOpenCode/Component/Dataset/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
{
"name": "Nikola Svitlica a.k.a TheCelavi",
"email": "thecelavi@runopencode.com"
},
{
"name": "Stefan Veljancic",
"email": "veljancicstefan@gmail.com"
}
],
"require": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ final class IterableCollector implements \IteratorAggregate, CollectorInterface
return $this->getIterator();
}
}

/**
* {@inheritdoc}
*/
Expand All @@ -45,7 +45,7 @@ final class IterableCollector implements \IteratorAggregate, CollectorInterface

/**
* Provides you with total number of iterated elements.
*
*
* @var non-negative-int
*/
public private(set) int $count = 0;
Expand Down Expand Up @@ -73,4 +73,4 @@ public function getIterator(): \Traversable
$this->count++;
}
}
}
}
110 changes: 110 additions & 0 deletions src/RunOpenCode/Component/Dataset/src/Model/Buffer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php

declare(strict_types=1);

namespace RunOpenCode\Component\Dataset\Model;

use RunOpenCode\Component\Dataset\Exception\LogicException;

/**
* Buffer of iterated items from collection.
*
* @template-covariant TKey
* @template-covariant TValue
*
* @phpstan-type ItemTuple = array{TKey, TValue}
*
* @implements \IteratorAggregate<TKey, TValue>
*/
final readonly class Buffer implements \IteratorAggregate, \Countable
{
/**
* Create new buffer.
*
* @param \ArrayObject<int, ItemTuple> $items Items within buffer.
*
* @internal
*/
public function __construct(private \ArrayObject $items)
{
// noop.
}

/**
* Get first item in buffer.
*
* @return Item<TKey, TValue>
*
* @phpstan-ignore-next-line generics.variance
*/
public function first(): Item
{
$first = $this->items[0] ?? throw new LogicException('Buffer is empty.');

return new Item($first[0], $first[1]);
}

/**
* Get last item in buffer.
*
* @return Item<TKey, TValue>
*
* @phpstan-ignore-next-line generics.variance
*/
public function last(): Item
{
$last = $this->items[\count($this->items) - 1] ?? throw new LogicException('Buffer is empty.');

return new Item($last[0], $last[1]);
}

/**
* Get all keys.
*
* @return list<TKey>
*/
public function keys(): array
{
$keys = [];

foreach ($this->items as [$key]) {
$keys[] = $key;
}

return $keys;
}

/**
* Get all values.
*
* @return list<TValue>
*/
public function values(): array
{
$values = [];

foreach ($this->items as [, $value]) {
$values[] = $value;
}

return $values;
}

/**
* {@inheritdoc}
*/
public function getIterator(): \Traversable
{
foreach ($this->items as [$key, $value]) {
yield $key => $value;
}
}

/**
* {@inheritdoc}
*/
public function count(): int
{
return $this->items->count();
}
}
88 changes: 88 additions & 0 deletions src/RunOpenCode/Component/Dataset/src/Model/Item.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace RunOpenCode\Component\Dataset\Model;

use RunOpenCode\Component\Dataset\Exception\OutOfBoundsException;

/**
* @template TKey
* @template TValue
*
* @implements \ArrayAccess<int, TKey|TValue>
*/
final readonly class Item implements \ArrayAccess
{
/**
* @param TKey $key
* @param TValue $value
*/
public function __construct(
private mixed $key,
private mixed $value
) {
// noop.
}

/**
* Get key.
*
* @return TKey
*/
public function key(): mixed
{
return $this->key;
}

/**
* Get value.
*
* @return TValue
*/
public function value(): mixed
{
return $this->value;
}

/**
* {@inheritdoc}
*/
public function offsetExists(mixed $offset): bool
{
return $offset === 0 || $offset === 1;
}

/**
* {@inheritdoc}
*
* @return ($offset is 0 ? TKey : TValue)
*/
public function offsetGet(mixed $offset): mixed
{
return match ($offset) {
0 => $this->key,
1 => $this->value,
default => throw new OutOfBoundsException($offset, $this, \sprintf(
'Item tuple does not have offset "%s".',
$offset
)),
};
}

/**
* {@inheritdoc}
*/
public function offsetSet(mixed $offset, mixed $value): void
{
throw new \BadMethodCallException('Item is immutable.');
}

/**
* {@inheritdoc}
*/
public function offsetUnset(mixed $offset): void
{
throw new \BadMethodCallException('Item is immutable.');
}
}
94 changes: 0 additions & 94 deletions src/RunOpenCode/Component/Dataset/src/Operator/Batch.php

This file was deleted.

59 changes: 59 additions & 0 deletions src/RunOpenCode/Component/Dataset/src/Operator/BufferCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace RunOpenCode\Component\Dataset\Operator;

use RunOpenCode\Component\Dataset\AbstractStream;
use RunOpenCode\Component\Dataset\Contract\OperatorInterface;
use RunOpenCode\Component\Dataset\Model\Buffer;

/**
* Buffer count operator.
*
* Iterates over given collection and creates a buffer of items with number of items
* up to given capacity.
*
* Yields created instances of {@see Buffer} for batch processing.
*
* @template TKey
* @template TValue
*
* @extends AbstractStream<int, Buffer<TKey, TValue>>
* @implements OperatorInterface<int, Buffer<TKey, TValue>>
*/
final class BufferCount extends AbstractStream implements OperatorInterface
{
/**
* @param iterable<TKey, TValue> $collection Collection to iterate over.
* @param positive-int $count How many items to buffer.
*/
public function __construct(
private readonly iterable $collection,
private readonly int $count = 1000,
) {
parent::__construct($collection);
}

/**
* {@inheritdoc}
*/
protected function iterate(): \Traversable
{
/** @var \ArrayObject<int, array{TKey, TValue}> $items */
$items = new \ArrayObject();

foreach ($this->collection as $key => $value) {
$items[] = [$key, $value];

if (\count($items) === $this->count) {
yield new Buffer($items);
$items = new \ArrayObject();
}
}

if (\count($items) !== 0) {
yield new Buffer($items);
}
}
}
Loading