modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									8612a9dae4
								
							
						
					
					
						commit
						8079d111cc
					
				
							
								
								
									
										29
									
								
								src/cache/CacheChannel.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								src/cache/CacheChannel.php
									
									
									
									
										vendored
									
									
								
							| @ -23,42 +23,19 @@ class CacheChannel extends CapacitorChannel implements IteratorAggregate { | ||||
|     "primary key (group_id, id, key_index)", | ||||
|   ]; | ||||
| 
 | ||||
|   static function with(CapacitorStorage $storage, ?iterable $rows=null, $cursorId=null): self { | ||||
|   static function with(?iterable $rows=null, $cursorId=null, ?CapacitorStorage $storage=null): self { | ||||
|     $storage ??= cache::storage(); | ||||
|     $channel = (new static($cursorId))->initStorage($storage); | ||||
|     if ($rows !== null) $channel->build($rows); | ||||
|     return $channel; | ||||
|   } | ||||
| 
 | ||||
|   static function verifix_id(&$cursorId): void { | ||||
|     $cursorId ??= utils::uuidgen(); | ||||
|     if (is_array($cursorId)) { | ||||
|       $keys = array_keys($cursorId); | ||||
|       if (array_key_exists("group_id", $cursorId)) $groupIdKey = "group_id"; | ||||
|       else $groupIdKey = $keys[1] ?? null; | ||||
|       $groupId = strval($cursorId[$groupIdKey] ?? ""); | ||||
|       if (array_key_exists("id", $cursorId)) $idKey = "id"; | ||||
|       else $idKey = $keys[0] ?? null; | ||||
|       $id = strval($cursorId[$idKey] ?? ""); | ||||
|     } else { | ||||
|       $groupId = ""; | ||||
|       $id = strval($cursorId); | ||||
|     } | ||||
|     # si le groupe ou le nom sont trop grand, en faire un hash
 | ||||
|     if (strlen($groupId) > 32) { | ||||
|       $groupId = md5($groupId); | ||||
|     } | ||||
|     if (strlen($id) > 128) { | ||||
|       $id = substr($id, 0, 128 - 32).md5($id); | ||||
|     } | ||||
|     $cursorId = ["group_id" => $groupId, "id" => $id]; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @param array|string $cursorId | ||||
|    */ | ||||
|   function __construct($cursorId) { | ||||
|     parent::__construct(); | ||||
|     self::verifix_id($cursorId); | ||||
|     cache::verifix_id($cursorId); | ||||
|     $this->cursorId = $cursorId; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/cache/CacheFile.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								src/cache/CacheFile.php
									
									
									
									
										vendored
									
									
								
							| @ -19,6 +19,11 @@ class CacheFile extends SharedFile { | ||||
| 
 | ||||
|   const EXT = ".cache"; | ||||
| 
 | ||||
|   static function with($data, ?string $file=null): self { | ||||
|     if ($data instanceof self) return $data; | ||||
|     else return new static($file, $data); | ||||
|   } | ||||
| 
 | ||||
|   protected function ensure_source($source): CacheData { | ||||
|     if ($source instanceof CacheData) return $source; | ||||
|     if (cv::subclass_of($source, CacheData::class)) return new $source(); | ||||
| @ -26,7 +31,7 @@ class CacheFile extends SharedFile { | ||||
|     throw ValueException::invalid_type($source, CacheData::class); | ||||
|   } | ||||
| 
 | ||||
|   function __construct($file, $data=null, ?array $params=null) { | ||||
|   function __construct(?string $file, $data=null, ?array $params=null) { | ||||
|     $file ??= path::join(sys_get_temp_dir(), utils::uuidgen()); | ||||
|     $file = path::ensure_ext($file, self::EXT); | ||||
|     $this->basedir = path::dirname($file); | ||||
|  | ||||
							
								
								
									
										68
									
								
								src/cache/CacheManager.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/cache/CacheManager.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,68 @@ | ||||
| <?php | ||||
| namespace nulib\cache; | ||||
| 
 | ||||
| use nulib\cl; | ||||
| 
 | ||||
| /** | ||||
|  * Class CacheManager: un gestionnaire de cache permettant de désactiver la mise | ||||
|  * en cache d'une valeur dans le cadre d'une session. | ||||
|  * | ||||
|  * en effet, si on désactive le cache, il doit être réactivé après que la valeur | ||||
|  * est calculée, pour éviter qu'une valeur soit calculée encore et encore dans | ||||
|  * une session de travail | ||||
|  */ | ||||
| class CacheManager { | ||||
|   function __construct(?array $includes=null, ?array $excludes=null) { | ||||
|     $this->shouldCaches = []; | ||||
|     $this->defaultCache = true; | ||||
|     $this->includes = $includes; | ||||
|     $this->excludes = $excludes; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @var array tableau {id => shouldCache} indiquant si l'élément id doit être | ||||
|    * mis en cache | ||||
|    */ | ||||
|   protected array $shouldCaches; | ||||
| 
 | ||||
|   /** | ||||
|    * @var bool valeur par défaut de shouldCache si la valeur n'est pas trouvée | ||||
|    * dans $shouldCache | ||||
|    */ | ||||
|   protected bool $defaultCache; | ||||
| 
 | ||||
|   /** | ||||
|    * @var array|null groupes à toujours inclure dans le cache. pour les | ||||
|    * identifiants de ces groupe, {@link self::shouldCache()} retourne toujours | ||||
|    * true. | ||||
|    * | ||||
|    * $excludes est prioritaire par rapport à $includes | ||||
|    */ | ||||
|   protected ?array $includes; | ||||
| 
 | ||||
|   /** | ||||
|    * @var array|null groupes à exclure de la mise en cache. la mise en cache est | ||||
|    * toujours calculée pour les identifiants de ces groupes. | ||||
|    */ | ||||
|   protected ?array $excludes; | ||||
| 
 | ||||
|   function setNoCache(bool $noCache=true, bool $reset=true): self { | ||||
|     if ($reset) $this->shouldCaches = []; | ||||
|     $this->defaultCache = !$noCache; | ||||
|     return $this; | ||||
|   } | ||||
| 
 | ||||
|   function shouldCache(string $id, ?string $groupId=null, bool $reset=true): bool { | ||||
|     if ($groupId !== null) { | ||||
|       $includes = $this->includes; | ||||
|       $shouldInclude = $includes !== null && in_array($groupId, $includes); | ||||
|       $excludes = $this->excludes; | ||||
|       $shouldExclude = $excludes !== null && in_array($groupId, $excludes); | ||||
|       if ($shouldInclude && !$shouldExclude) return true; | ||||
|     } | ||||
|     $cacheId = "$groupId-$id"; | ||||
|     $shouldCache = cl::get($this->shouldCaches, $cacheId, $this->defaultCache); | ||||
|     $this->shouldCaches[$cacheId] = $reset?: $shouldCache; | ||||
|     return $shouldCache; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										61
									
								
								src/cache/cache.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										61
									
								
								src/cache/cache.php
									
									
									
									
										vendored
									
									
								
							| @ -4,6 +4,7 @@ namespace nulib\cache; | ||||
| use nulib\app; | ||||
| use nulib\db\CapacitorStorage; | ||||
| use nulib\db\sqlite\SqliteStorage; | ||||
| use nulib\ext\utils; | ||||
| use nulib\php\func; | ||||
| 
 | ||||
| class cache { | ||||
| @ -15,7 +16,7 @@ class cache { | ||||
| 
 | ||||
|   protected static ?CapacitorStorage $storage = null; | ||||
| 
 | ||||
|   protected static function storage(): CapacitorStorage { | ||||
|   static function storage(): CapacitorStorage { | ||||
|     return self::$storage ??= new SqliteStorage(self::dbfile()); | ||||
|   } | ||||
| 
 | ||||
| @ -23,13 +24,59 @@ class cache { | ||||
|     return self::$storage = $storage; | ||||
|   } | ||||
| 
 | ||||
|   static function all(?iterable $rows, $cursorId=null): iterable { | ||||
|     CacheChannel::verifix_id($cursorId); | ||||
|     $file = "row-{$cursorId["group_id"]}-{$cursorId["id"]}"; | ||||
|     $cache = new CacheFile($file, function() use ($rows, $cursorId) { | ||||
|       CacheChannel::with(self::storage(), null, $cursorId)->build($rows); | ||||
|   protected static ?CacheManager $manager = null; | ||||
| 
 | ||||
|   static function manager(): CacheManager { | ||||
|     return self::$manager ??= new CacheManager(); | ||||
|   } | ||||
| 
 | ||||
|   static function set_manager(CacheManager $manager): CacheManager { | ||||
|     return self::$manager = $manager; | ||||
|   } | ||||
| 
 | ||||
|   static function nc(bool $noCache=true, bool $reset=false): void { | ||||
|     self::manager()->setNoCache($noCache, $reset); | ||||
|   } | ||||
| 
 | ||||
|   protected static function should_cache(string $id, ?string $groupId=null, bool $reset=true): bool { | ||||
|     return self::manager()->shouldCache($id, $groupId, $reset); | ||||
|   } | ||||
| 
 | ||||
|   static function verifix_id(&$cacheId): void { | ||||
|     $cacheId ??= utils::uuidgen(); | ||||
|     if (is_array($cacheId)) { | ||||
|       $keys = array_keys($cacheId); | ||||
|       if (array_key_exists("id", $cacheId)) $idKey = "id"; | ||||
|       else $idKey = $keys[0] ?? null; | ||||
|       $id = strval($cacheId[$idKey] ?? ""); | ||||
|       if (array_key_exists("group_id", $cacheId)) $groupIdKey = "group_id"; | ||||
|       else $groupIdKey = $keys[1] ?? null; | ||||
|       $groupId = strval($cacheId[$groupIdKey] ?? ""); | ||||
|     } else { | ||||
|       $id = strval($cacheId); | ||||
|       $groupId = ""; | ||||
|     } | ||||
|     # si le groupe ou le nom sont trop grand, en faire un hash
 | ||||
|     if (strlen($groupId) > 32) $groupId = md5($groupId); | ||||
|     if (strlen($id) > 128) $id = substr($id, 0, 128 - 32).md5($id); | ||||
|     $cacheId = ["group_id" => $groupId, "id" => $id]; | ||||
|   } | ||||
| 
 | ||||
|   static function get(callable $compute, $dataId=null, ?string $file=null) { | ||||
|     self::verifix_id($dataId); | ||||
|     $file ??= "{$dataId["group_id"]}-{$dataId["id"]}"; | ||||
|     $noCache = !self::should_cache($dataId["id"], $dataId["group_id"]); | ||||
|     return CacheFile::with($compute, $file)->get(null, $noCache); | ||||
|   } | ||||
| 
 | ||||
|   static function all(?iterable $rows, $cursorId=null, ?string $file=null): iterable { | ||||
|     self::verifix_id($cursorId); | ||||
|     $file ??= "{$cursorId["group_id"]}-{$cursorId["id"]}--rows"; | ||||
|     $ccursorId = new CacheFile($file, function() use ($rows, $cursorId) { | ||||
|       CacheChannel::with(null, $cursorId)->build($rows); | ||||
|       return $cursorId; | ||||
|     }); | ||||
|     return CacheChannel::with(self::storage(), null, $cache->get()); | ||||
|     $noCache = !self::should_cache($cursorId["id"], $cursorId["group_id"]); | ||||
|     return CacheChannel::with(null, $ccursorId->get(null, $noCache)); | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										2
									
								
								tests/cache/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								tests/cache/.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,2 +1,2 @@ | ||||
| /capacitor.db* | ||||
| /*.db* | ||||
| /*.cache | ||||
|  | ||||
							
								
								
									
										2
									
								
								tests/cache/CursorChannelTest.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								tests/cache/CursorChannelTest.php
									
									
									
									
										vendored
									
									
								
							| @ -11,7 +11,7 @@ class CursorChannelTest extends _TestCase { | ||||
|       ["a" => 1, "b" => 2], | ||||
|     ]; | ||||
| 
 | ||||
|     $channel = CacheChannel::with(self::$storage, $data, "numbers"); | ||||
|     $channel = CacheChannel::with($data, "numbers", self::$storage); | ||||
|     $count = 0; | ||||
|     foreach ($channel as $key => $item) { | ||||
|       msg::info("one: $key => {$item["a"]}"); | ||||
|  | ||||
							
								
								
									
										2
									
								
								tests/cache/_TestCase.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								tests/cache/_TestCase.php
									
									
									
									
										vendored
									
									
								
							| @ -12,7 +12,7 @@ class _TestCase extends TestCase { | ||||
|   static function setUpBeforeClass(): void { | ||||
|     parent::setUpBeforeClass(); | ||||
|     msg::set_messenger_class(StdMessenger::class); | ||||
|     self::$storage = new SqliteStorage(__DIR__."/capacitor.db"); | ||||
|     self::$storage = new SqliteStorage(__DIR__."/cache.db"); | ||||
|     cache::set_storage(self::$storage); | ||||
|   } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										45
									
								
								tests/cache/cacheTest.php
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								tests/cache/cacheTest.php
									
									
									
									
										vendored
									
									
								
							| @ -1,16 +1,18 @@ | ||||
| <?php | ||||
| namespace nulib\cache; | ||||
| 
 | ||||
| use nulib\cl; | ||||
| use nulib\output\msg; | ||||
| 
 | ||||
| class cacheTest extends _TestCase { | ||||
|   const DATA = [ | ||||
|     "fr" => ["a" => "un", "b" => "deux"], | ||||
|     "eng" => ["a" => "one", "b" => "two"], | ||||
|     ["a" => 1, "b" => 2], | ||||
|   ]; | ||||
| 
 | ||||
|   function gendata() { | ||||
|     $data = [ | ||||
|       "fr" => ["a" => "un", "b" => "deux"], | ||||
|       "eng" => ["a" => "one", "b" => "two"], | ||||
|       ["a" => 1, "b" => 2], | ||||
|     ]; | ||||
|     foreach ($data as $key => $item) { | ||||
|     foreach (self::DATA as $key => $item) { | ||||
|       msg::info("yield $key"); | ||||
|       yield $key => $item; | ||||
|       sleep(2); | ||||
| @ -18,13 +20,36 @@ class cacheTest extends _TestCase { | ||||
|     msg::info("fin gendata"); | ||||
|   } | ||||
| 
 | ||||
|   function testUsage() { | ||||
|     $data = cache::all($this->gendata(),"gendata"); | ||||
|   function _testRows(iterable $rows) { | ||||
|     $count = 0; | ||||
|     foreach ($data as $key => $item) { | ||||
|       msg::info("got $key => ".var_export($item, true)); | ||||
|     foreach ($rows as $key => $row) { | ||||
|       msg::info("got $key => ".var_export($row, true)); | ||||
|       $count++; | ||||
|     } | ||||
|     self::assertSame(3, $count); | ||||
|   } | ||||
| 
 | ||||
|   function testUsage() { | ||||
|     msg::section("all"); | ||||
|     $rows = cache::all($this->gendata(),"gendata"); | ||||
|     $this->_testRows($rows); | ||||
| 
 | ||||
|     msg::section("get"); | ||||
|     $rows = cache::get(function() { | ||||
|       return self::DATA; | ||||
|     },"gendata"); | ||||
|     $this->_testRows($rows); | ||||
|   } | ||||
| 
 | ||||
|   function testNc() { | ||||
|     cache::nc(); | ||||
| 
 | ||||
|     msg::section("first pass"); | ||||
|     $rows = cache::all($this->gendata(),"gendata"); | ||||
|     $this->_testRows($rows); | ||||
| 
 | ||||
|     msg::section("second pass"); | ||||
|     $rows = cache::all($this->gendata(),"gendata"); | ||||
|     $this->_testRows($rows); | ||||
|   } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user