streams/Code/Lib/Hashpath.php

66 lines
2.2 KiB
PHP
Raw Normal View History

2020-08-18 06:35:05 +00:00
<?php
2022-02-16 04:08:28 +00:00
namespace Code\Lib;
2020-08-18 06:35:05 +00:00
2022-06-22 10:32:08 +00:00
use Code\Storage\Stdio;
2020-08-18 06:35:05 +00:00
/*
2022-02-16 04:08:28 +00:00
* Code\Lib\Hashpath
2020-08-18 06:35:05 +00:00
*
* Creates hashed directory structures for fast access and resistance to overloading any single directory with files.
*
2022-08-28 06:06:24 +00:00
* Takes $url which could be any string
2020-08-18 06:35:05 +00:00
* a $prefix which is where to place the hash directory in the filesystem, default is current directory
* use an empty string for $prefix to place hash directories directly off the root directory
* an optional $depth to indicate the hash level
* $depth = 1, 256 directories, suitable for < 384K records/files
* $depth = 2, 65536 directories, suitable for < 98M records/files
* $depth = 3, 16777216 directories, suitable for < 2.5B records/files
* ...
* The total number of records anticipated divided by the number of hash directories should generally be kept to
* less than 1500 entries for optimum performance though this varies by operating system and filesystem type.
2021-12-03 03:01:39 +00:00
* ext4 uses 32 bit inode numbers (~4B record limit) so use caution or alternative filesystem types with $depth above 3.
2020-08-18 06:35:05 +00:00
* an optional $mkdir (boolean) to recursively create the directory (ignoring errors) before returning
*
* examples: for a $url of 'abcdefg' and prefix of 'path' the following paths are returned for $depth = 1 and $depth = 3
* path/7d/7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
* path/7d/1a/54/7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a
*
*
*/
2021-12-02 23:02:31 +00:00
class Hashpath
{
2020-08-18 06:35:05 +00:00
2022-08-28 06:06:24 +00:00
/**
* @param string $url
* @param string $prefix
* @param int $depth
* @param bool $mkdir
* @return string
*/
public static function path(string $url, string $prefix = '.', int $depth = 1, bool $mkdir = true): string
2021-12-02 23:02:31 +00:00
{
2023-11-04 22:15:53 +00:00
$hash = hash('sha256', isset($url) ? $url : '');
2021-12-02 23:02:31 +00:00
$start = 0;
$slice = 2;
if ($depth < 1) {
$depth = 1;
}
$sluglen = $depth * $slice;
2020-08-18 06:35:05 +00:00
2021-12-02 23:02:31 +00:00
do {
$slug = substr($hash, $start, $slice);
$prefix .= '/' . $slug;
$start += $slice;
$sluglen -= $slice;
} while ($sluglen);
if ($mkdir) {
2022-06-22 10:32:08 +00:00
Stdio::mkdir($prefix, STORAGE_DEFAULT_PERMISSIONS, true);
2021-12-02 23:02:31 +00:00
}
return $prefix . '/' . $hash;
}
2020-08-18 06:35:05 +00:00
}