Skip to content

Commit c352f46

Browse files
committed
Introduce GeneratorStorage and enhance data structure hierarchy.
**Detailed Description:** 1. **New `GeneratorStorage` Implementation:** - Added `GeneratorStorage` class to facilitate lazy, generator-based data storage, ideal for streaming large or infinite datasets. - Implemented key methods: `entries()`, `keys()`, `values()` for efficient data access via generators. - Integrated into the `Storage` abstraction layer and relevant autoload classmaps. 2. **Updates to `Storage` Interface:** - Refactored the `Storage` contract to directly define `entries()`, `keys()`, and `values()` methods, removing legacy behavior dependencies (`Countable`, `Enumerable`). - Enhanced overall modularity and data access capabilities. 3. **Enhancements to Sequential `Sequence` Class:** - Updated `Sequence` to leverage the improved `Storage` abstraction and the new `Iterator` utilities for counting and traversing elements. - Refactored to ensure compatibility with generator-based storages for sequential data. 4. **Unit Tests for Coverage:** - Created unit test files for `GeneratorStorage` and `ArrStorage` to validate their functionality: - Tests for `entries()`, `keys()`, `values()`. - Integration with `Sequence` verified through `SequenceTest`. - Ensured accurate test coverage with parameterized data across edge cases. 5. **Autoload and Classmap Updates:** - Registered `GeneratorStorage` in the `classmap` and `compiled classmap` for optimized dependency loading. **Key Benefits:** - Establishes new lazy storage options via `GeneratorStorage` for scalable, memory-efficient operations. - Strengthens the FireHub ecosystem's modularity and extensibility for data persistence structures. - Backward-compatible with existing abstractions while enabling advanced usage scenarios.
1 parent 6686425 commit c352f46

12 files changed

Lines changed: 380 additions & 20 deletions

File tree

dist/core.min.phar

1.09 KB
Binary file not shown.

dist/core.phar

3.68 KB
Binary file not shown.

src/support/autoload/classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
\FireHub\Core\Support\DataStructure\Linear\Sequence::class => __DIR__.'/../../support/datastructure/linear/firehub.Sequence.php',
8585
\FireHub\Core\Support\DataStructure\Storage::class => __DIR__.'/../../support/datastructure/firehub.Storage.php',
8686
\FireHub\Core\Support\DataStructure\Storage\ArrStorage::class => __DIR__.'/../../support/datastructure/storage/firehub.ArrStorage.php',
87+
\FireHub\Core\Support\DataStructure\Storage\GeneratorStorage::class => __DIR__.'/../../support/datastructure/storage/firehub.GeneratorStorage.php',
8788
\FireHub\Core\Support\LowLevel::class => __DIR__.'/../../support/firehub.LowLevel.php',
8889
\FireHub\Core\Support\LowLevel\Arr::class => __DIR__.'/../../support/lowlevel/firehub.Arr.php',
8990
\FireHub\Core\Support\LowLevel\CharMB::class => __DIR__.'/../../support/lowlevel/firehub.CharMB.php',

src/support/autoload/loader/firehub.CompiledClassmap.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,10 @@ public function __invoke (string $class):void {
268268
require __DIR__.'/../../../support/datastructure/storage/firehub.ArrStorage.php';
269269
return;
270270

271+
case \FireHub\Core\Support\DataStructure\Storage\GeneratorStorage::class:
272+
require __DIR__.'/../../../support/datastructure/storage/firehub.GeneratorStorage.php';
273+
return;
274+
271275
case \FireHub\Core\Support\LowLevel::class:
272276
require __DIR__.'/../../../support/firehub.LowLevel.php';
273277
return;

src/support/datastructure/firehub.Linear.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
*
2626
* @template TValue
2727
*
28-
* @extends \FireHub\Core\Support\Contracts\DataStructure<mixed, TValue>
28+
* @extends \FireHub\Core\Support\Contracts\DataStructure<int, TValue>
2929
*/
3030
interface Linear extends DataStructure {}

src/support/datastructure/firehub.Storage.php

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313

1414
namespace FireHub\Core\Support\DataStructure;
1515

16-
use FireHub\Core\Support\DataStructure\Behavior\ {
17-
Countable, Enumerable
18-
};
19-
2016
/**
2117
* ### Storage Abstraction Layer
2218
*
@@ -26,7 +22,31 @@
2622
*
2723
* @template TKey
2824
* @template TValue
29-
*
30-
* @extends \FireHub\Core\Support\DataStructure\Behavior\Enumerable<TKey, TValue>
3125
*/
32-
interface Storage extends Countable, Enumerable {}
26+
interface Storage {
27+
28+
/**
29+
* ### Get all entries from the storage
30+
* @since 1.0.0
31+
*
32+
* @return iterable<TKey, TValue>
33+
*/
34+
public function entries ():iterable;
35+
36+
/**
37+
* ### Get all keys from the storage
38+
* @since 1.0.0
39+
*
40+
* @return iterable<int, TKey>
41+
*/
42+
public function keys ():iterable;
43+
44+
/**
45+
* ### Get all values from the storage
46+
* @since 1.0.0
47+
*
48+
* @return iterable<int, TValue>
49+
*/
50+
public function values ():iterable;
51+
52+
}

src/support/datastructure/linear/firehub.Sequence.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use FireHub\Core\Support\DataStructure\Behavior\ {
2020
Countable, Enumerable
2121
};
22+
use FireHub\Core\Support\LowLevel\Iterator;
2223
use Traversable;
2324

2425
/**
@@ -31,7 +32,7 @@
3132
* @template TValue
3233
*
3334
* @implements \FireHub\Core\Support\DataStructure\Linear<TValue>
34-
* @implements \FireHub\Core\Support\DataStructure\Behavior\Enumerable<mixed, TValue>
35+
* @implements \FireHub\Core\Support\DataStructure\Behavior\Enumerable<int, TValue>
3536
*/
3637
class Sequence implements Linear, Countable, Enumerable {
3738

@@ -41,7 +42,7 @@ class Sequence implements Linear, Countable, Enumerable {
4142
*
4243
* @uses \FireHub\Core\Support\DataStructure\Storage As parameter.
4344
*
44-
* @param \FireHub\Core\Support\DataStructure\Storage<mixed, TValue> $storage <p>
45+
* @param \FireHub\Core\Support\DataStructure\Storage<covariant mixed, TValue> $storage <p>
4546
* Underlying storage data.
4647
* </p>
4748
*
@@ -60,27 +61,30 @@ public function __construct (
6061
*
6162
* $collection = new Sequence(new ArrStorage(['John', 'Jane', 'Jane', 'Jane', 'Richard', 'Richard']));
6263
*
63-
* // ['firstname' => 'John', 'lastname' => 'Doe', 'age' => 25, 10 => 2]
64+
* // 6
6465
* </code>
6566
*
6667
* @since 1.0.0
6768
*
68-
* @uses \FireHub\Core\Support\DataStructure\Storage::count() To count the number of elements in the sequence.
69+
* @uses \FireHub\Core\Support\LowLevel\Iterator::count() To count the number of elements in the sequence.
70+
* @uses \FireHub\Core\Support\DataStructure\Storage::entries() To get the entries of the storage for counting.
6971
*/
7072
public function count ():int {
7173

72-
return $this->storage->count();
74+
return Iterator::count($this->storage->entries());
7375

7476
}
7577

7678
/**
7779
* @inheritDoc
7880
*
7981
* @since 1.0.0
82+
*
83+
* @uses \FireHub\Core\Support\DataStructure\Storage::values() To get the values of the storage for iteration.
8084
*/
8185
public function getIterator ():Traversable {
8286

83-
return $this->storage;
87+
yield from $this->storage->values();
8488

8589
}
8690

src/support/datastructure/storage/firehub.ArrStorage.php

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
use FireHub\Core\Support\DataStructure\Storage;
1717
use FireHub\Core\Support\LowLevel\Arr;
18-
use Traversable;
1918

2019
/**
2120
* ### Array-Based Storage
@@ -49,23 +48,36 @@ public function __construct (
4948
* @inheritDoc
5049
*
5150
* @since 1.0.0
51+
*/
52+
public function entries ():iterable {
53+
54+
return $this->data;
55+
56+
}
57+
58+
/**
59+
* @inheritDoc
5260
*
53-
* @uses \FireHub\Core\Support\LowLevel\Arr::count() To count the number of elements in the array.
61+
* @since 1.0.0
62+
*
63+
* @uses \FireHub\Core\Support\LowLevel\Arr::keys() For efficient key retrieval.
5464
*/
55-
public function count ():int {
65+
public function keys ():iterable {
5666

57-
return Arr::count($this->data);
67+
return Arr::keys($this->data);
5868

5969
}
6070

6171
/**
6272
* @inheritDoc
6373
*
6474
* @since 1.0.0
75+
*
76+
* @uses \FireHub\Core\Support\LowLevel\Arr::values() For efficient value retrieval.
6577
*/
66-
public function getIterator ():Traversable {
78+
public function values ():iterable {
6779

68-
yield from $this->data;
80+
return Arr::values($this->data);
6981

7082
}
7183

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php declare(strict_types = 1);
2+
3+
/**
4+
* This file is part of the FireHub Project ecosystem
5+
*
6+
* @author Danijel Galić <danijel.galic@outlook.com>
7+
* @copyright 2026 The FireHub Project - All rights reserved
8+
* @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0
9+
*
10+
* @php-version 7.0
11+
* @package Core\Support
12+
*/
13+
14+
namespace FireHub\Core\Support\DataStructure\Storage;
15+
16+
use FireHub\Core\Support\DataStructure\Storage;
17+
use Closure, Generator;
18+
19+
/**
20+
* ### Generator-Based Storage
21+
*
22+
* Lazy, streaming-oriented storage implementation that produces elements on demand. Ideal for large or infinite
23+
* datasets where full materialization is not possible or desired.
24+
* @since 1.0.0
25+
*
26+
* @template TKey
27+
* @template TValue
28+
*
29+
* @implements \FireHub\Core\Support\DataStructure\Storage<TKey, TValue>
30+
*/
31+
class GeneratorStorage implements Storage {
32+
33+
/**
34+
* ### Constructor
35+
* @since 1.0.0
36+
*
37+
* @param Closure():Generator<TKey, TValue> $callable <p>
38+
* The callable that produces the generator.
39+
* </p>
40+
*
41+
* @return void
42+
*/
43+
public function __construct (
44+
protected Closure $callable
45+
) {}
46+
47+
/**
48+
* @inheritDoc
49+
*
50+
* @since 1.0.0
51+
*
52+
* @uses \FireHub\Core\Support\DataStructure\Storage\GeneratorStorage::create() To produce the generator for
53+
* entries.
54+
*/
55+
public function entries ():iterable {
56+
57+
return $this->create();
58+
59+
}
60+
61+
/**
62+
* @inheritDoc
63+
*
64+
* @since 1.0.0
65+
*
66+
* @uses \FireHub\Core\Support\DataStructure\Storage\GeneratorStorage::create() To produce the generator for
67+
* values.
68+
*/
69+
public function keys ():iterable {
70+
71+
foreach ($this->create() as $key => $value)
72+
yield $key;
73+
74+
}
75+
76+
/**
77+
* @inheritDoc
78+
*
79+
* @since 1.0.0
80+
*
81+
* @uses \FireHub\Core\Support\DataStructure\Storage\GeneratorStorage::create() To produce the generator for
82+
* keys.
83+
*/
84+
public function values ():iterable {
85+
86+
foreach ($this->create() as $value)
87+
yield $value;
88+
89+
}
90+
91+
/**
92+
* ### Creates the generator
93+
* @since 1.0.0
94+
*
95+
* @return Generator<TKey, TValue> The generator produced by the callable.
96+
*/
97+
private function create ():Generator {
98+
99+
yield from ($this->callable)();
100+
101+
}
102+
103+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php declare(strict_types = 1);
2+
3+
/**
4+
* This file is part of the FireHub Project ecosystem
5+
*
6+
* @author Danijel Galić <danijel.galic@outlook.com>
7+
* @copyright 2026 The FireHub Project - All rights reserved
8+
* @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0
9+
*
10+
* @package Core\Test
11+
*/
12+
13+
namespace FireHub\Tests\Unit\Support\DataStructure\Linear;
14+
15+
use FireHub\Core\Testing\Base;
16+
use FireHub\Core\Support\DataStructure\Linear\Sequence;
17+
use FireHub\Core\Support\DataStructure\Storage\ArrStorage;
18+
use PHPUnit\Framework\Attributes\ {
19+
CoversClass, Group, Small, TestWith
20+
};
21+
22+
/**
23+
* ### Test Sequence Data Structure
24+
* @since 1.0.0
25+
*/
26+
#[Small]
27+
#[Group('support')]
28+
#[CoversClass(Sequence::class)]
29+
final class SequenceTest extends Base {
30+
31+
/**
32+
* @since 1.0.0
33+
*
34+
* @param int $expected
35+
* @param array $array
36+
*
37+
* @return void
38+
*/
39+
#[TestWith([6, ['John', 'Jane', 'Jane', 'Jane', 'Richard', 'Richard']])]
40+
public function testCount (int $expected, array $array):void {
41+
42+
self::assertSame($expected, new Sequence(new ArrStorage($array))->count());
43+
44+
}
45+
46+
}

0 commit comments

Comments
 (0)