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
8 changes: 4 additions & 4 deletions src/GetSequence.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ trait GetSequence
* Generates a sequence number based on the current time.
*
* @param int $dateTime The current time.
* @param string $machineId The machine ID.
* @param int $machineId The machine ID.
* @param string $type The type identifier.
* @param int $maxSequence The maximum sequence number.
* @param int $maxSequenceLength The maximum length of the sequence number.
* @return int The generated sequence number, or `0` if lock was not acquired.
*/
private static function sequence(int $dateTime, string $machineId, string $type, int $maxSequence = 0): int
private static function sequence(int $dateTime, int $machineId, string $type, int $maxSequenceLength = 0): int
{
self::$fileLocation ??= sys_get_temp_dir() . DIRECTORY_SEPARATOR . "uid-$type-$machineId.seq";

// Attempt to acquire a lock
$handle = self::acquireLock();
if (!$handle) {
return getmypid() % ($maxSequence + 1);
return getmypid() % ((-1 ^ (-1 << $maxSequenceLength)) + 1);
}

// Update sequence
Expand Down
6 changes: 3 additions & 3 deletions src/TBSL.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static function generate(int $machineId = 0, bool $sequenced = false): st
return strtoupper(sprintf(
'%015s%05s',
$storeData,
substr(self::sequencedGenerate($machineId, $sequenced, (int)$timeSequence), -1, 5)
substr(self::sequencedGenerate($machineId, $sequenced, (int)$timeSequence), 0, 5)
));
}

Expand Down Expand Up @@ -62,7 +62,7 @@ private static function sequencedGenerate(int $machineId, bool $enableSequence,
public static function parse(string $tbsl): array
{
$data = [
'isValid' => preg_match('/^[0-9A-F]{20}$/', $tbsl),
'isValid' => (bool)preg_match('/^[0-9A-F]{20}$/', $tbsl),
'time' => null,
'machineId' => null,
];
Expand All @@ -73,7 +73,7 @@ public static function parse(string $tbsl): array

$storeData = base_convert(substr($tbsl, 0, 15), 16, 10);
$data['time'] = new DateTimeImmutable('@' . substr($storeData, 0, 10) . '.' . substr($storeData, 10, 6));
$data['machineId'] = substr($storeData, -2);
$data['machineId'] = (int)substr($storeData, -2);

return $data;
}
Expand Down
44 changes: 43 additions & 1 deletion tests/SnowflakeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,53 @@

use Infocyph\UID\Snowflake;

test('Basic', function () {
test('Snowflake Basic Functionality', function () {
$sf = Snowflake::generate();
$parsed = Snowflake::parse($sf);

expect($parsed['time']->getTimestamp())->toBeBetween(time() - 1, time())
->and($parsed['worker_id'])->toBe(0)
->and($parsed['datacenter_id'])->toBe(0);
});

test('Snowflake ID Uniqueness', function () {
$id1 = Snowflake::generate();
usleep(10);
$id2 = Snowflake::generate();

expect($id1)->not->toBe($id2);
});

test('Snowflake Sequential Order', function () {
$id1 = Snowflake::generate();
usleep(10);
$id2 = Snowflake::generate();

expect((int) $id2)->toBeGreaterThan((int) $id1);
});

test('Snowflake Datacenter and Worker Differentiation', function () {
$id1 = Snowflake::generate(1, 1);
$id2 = Snowflake::generate(2, 2);

$parsed1 = Snowflake::parse($id1);
$parsed2 = Snowflake::parse($id2);

expect($parsed1['worker_id'])->not->toBe($parsed2['worker_id'])
->and($parsed1['datacenter_id'])->not->toBe($parsed2['datacenter_id']);
});

test('Snowflake Max Sequence Handling', function () {
$maxSeq = (-1 ^ (-1 << 12));

$id1 = Snowflake::generate();
for ($i = 0; $i <= $maxSeq; $i++) {
$id1 = Snowflake::generate();
}
usleep(10);
$id2 = Snowflake::generate();

expect((int) $id2)->toBeGreaterThan((int) $id1);
});


42 changes: 41 additions & 1 deletion tests/SonyflakeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,50 @@

use Infocyph\UID\Sonyflake;

test('Basic', function () {
test('Sonyflake Basic Functionality', function () {
$sf = Sonyflake::generate();
$parsed = Sonyflake::parse($sf);

expect($parsed['time']->getTimestamp())->toBeBetween(time() - 1, time())
->and($parsed['machine_id'])->toBe(0);
});

test('Sonyflake ID Uniqueness', function () {
$id1 = Sonyflake::generate();
usleep(10);
$id2 = Sonyflake::generate();

expect($id1)->not->toBe($id2);
});

test('Sonyflake Sequential Order', function () {
$id1 = Sonyflake::generate();
usleep(10);
$id2 = Sonyflake::generate();

expect((int) $id2)->toBeGreaterThan((int) $id1);
});

test('Sonyflake Machine ID Differentiation', function () {
$id1 = Sonyflake::generate(1);
$id2 = Sonyflake::generate(2);

$parsed1 = Sonyflake::parse($id1);
$parsed2 = Sonyflake::parse($id2);

expect($parsed1['machine_id'])->not->toBe($parsed2['machine_id']);
});

test('Sonyflake Max Sequence Handling', function () {
$maxSeq = (-1 ^ (-1 << 8));

$id1 = Sonyflake::generate();
for ($i = 0; $i <= $maxSeq; $i++) {
$id1 = Sonyflake::generate();
}
usleep(10);
$id2 = Sonyflake::generate();

expect((int) $id2)->toBeGreaterThan((int) $id1);
});

33 changes: 30 additions & 3 deletions tests/TBSLTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,37 @@

use Infocyph\UID\TBSL;

test('Basic', function () {
test('TBSL Basic Functionality', function () {
$sf = TBSL::generate();
$parsed = TBSL::parse($sf);
expect($parsed['time']->getTimestamp())->toBeBetween(time() - 1, time())
->and($parsed['machineId'])->toBe('00');
expect($parsed['isValid'])->toBeTrue()
->and($parsed['time']->getTimestamp())->toBeBetween(time() - 1, time())
->and($parsed['machineId'])->toBe(0);
});

test('TBSL ID Uniqueness', function () {
$id1 = TBSL::generate();
usleep(10); // Ensure slight time difference
$id2 = TBSL::generate();

expect($id1)->not->toBe($id2);
});

test('TBSL Sequential Order', function () {
$id1 = TBSL::generate();
usleep(10);
$id2 = TBSL::generate();

expect(hexdec($id2))->toBeGreaterThan(hexdec($id1));
});

test('TBSL Machine ID Differentiation', function () {
$id1 = TBSL::generate(1);
$id2 = TBSL::generate(2);

$parsed1 = TBSL::parse($id1);
$parsed2 = TBSL::parse($id2);

expect($parsed1['machineId'])->not->toBe($parsed2['machineId']);
});

Loading