tasoft / cached-generator
v0.9.10
2023-02-06 17:06 UTC
Requires
- php: >=7.2
Requires (Dev)
- phpunit/phpunit: ^9
This package is auto-updated.
Last update: 2024-09-06 20:26:57 UTC
README
问题
生成器是一个单向迭代器。
从文件、数据库或其他地方获取资源会消耗性能。在那里我喜欢使用生成器来只加载真正需要的内容。
I want to load a user with the username "admin"
Of course using MySQL you can create a specific request.
But If you do not know the sources, you need to iterate over all users and check, if one matches to the username.
With common iterators PHP will load all users first and then you have the possibility to pick the right one.
Using generators you may load user by user and check. If found, stop iteration.
但如果你想再次查找一个用户呢?
你不能回滚生成器。
<?php $yieldCount = 0; $gen = function () use(&$yieldCount) { $yieldCount++; yield "test-user"; $yieldCount++; yield "admin"; $yieldCount++; yield "normal-user"; $yieldCount++; yield "root"; $yieldCount++; yield "anonymous"; }; foreach ($gen() as $value) { echo "$value\n"; } /** Output: test-user admin normal-user root anonymous */ echo $yieldCount; // 5 // searching for admin $yieldCount = 0; $user = NULL; foreach ($gen() as $value) { if($value == "admin") { $user = $value; break; } } if($user) echo "Administrator found at iteration $yieldCount.\n"; // Output: Administrator found at iteration 2. // Now you need information about the root user: $yieldCount = 0; $user = NULL; foreach ($gen() as $value) { if($value == "root") { $user = $value; break; } } if($user) echo "Administrator found at iteration $yieldCount.\n"; // Output: Administrator found at iteration 4. // As you see, the generator need to restart. // Of course, you might continue with the same generator, but if the root user came before admin, you'll never get it.
解决方案:我的Cached Generator
它是一个对象,它接受一个生成器,它的调用会转发到生成器。
但除此之外,它还会缓存生成的值。
再次迭代时,它将开始使用缓存的值,并继续从生成器生成,直到生成器不再有效。
<?php use TASoft\Util\CachedGenerator; $yieldCount = 0; $gen = new CachedGenerator( ( function () use(&$yieldCount) { $yieldCount++; yield "test-user"; $yieldCount++; yield "admin"; $yieldCount++; yield "normal-user"; $yieldCount++; yield "root"; $yieldCount++; yield "anonymous"; } ) /* directly call the closure */ () ); $yieldCount = 0; $user = NULL; foreach ($gen() as $value) { if($value == "admin") { $user = $value; break; } } if($user) echo "Administrator found at iteration $yieldCount.\n"; // Output: Administrator found at iteration 2. // Now you need information about the root user: $yieldCount = 0; $user = NULL; foreach ($gen() as $value) { if($value == "root") { $user = $value; break; } } if($user) echo "Administrator found at iteration $yieldCount.\n"; // Output: Administrator found at iteration 2. // It is 2 again because the first two users are cached and the generator is not called. // After the cache end is reached, the cached generator will continue forwarding to the original generator.