Skip to content

Commit

Permalink
Optimize commitData processing
Browse files Browse the repository at this point in the history
Library:
- Subjects without duplicates where processed as a duplicate.
- First duplicate subject was altered and then unset.
- Conversion of hashes elements to an array was inefficient.

PHPUnit tests:
- First instance of duplicates is now kept instead of last.
  Updated Expected result for relevant tests.
  • Loading branch information
DigiLive committed Oct 23, 2020
1 parent 31d33af commit 6dc2bee
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 29 deletions.
32 changes: 12 additions & 20 deletions src/GitChangeLog.php
Expand Up @@ -361,12 +361,12 @@ public function fetchCommitData($force = false): array
$commitData[$previousTag]['subjects'] =
explode(
"\n",
shell_exec("git $gitPath log $tagRange $includeMergeCommits --pretty=format:%s --reverse")
shell_exec("git $gitPath log $tagRange $includeMergeCommits --pretty=format:%s")
);
$commitData[$previousTag]['hashes'] =
explode(
"\n",
shell_exec("git $gitPath log $tagRange $includeMergeCommits --pretty=format:%h --reverse")
shell_exec("git $gitPath log $tagRange $includeMergeCommits --pretty=format:%h")
);
$previousTag = $tag;
}
Expand All @@ -393,28 +393,20 @@ public function fetchCommitData($force = false): array
private function processCommitData(): void
{
foreach ($this->commitData as $tag => &$data) {
// Remove duplicates per tag.
foreach ($data['subjects'] as $subjectKey => $subject) {
// Get indexes of current subject.
// Merge duplicate subjects per tag.
foreach ($data['subjects'] as $subjectKey => &$subject) {
// Convert hash element into an array.
$data['hashes'][$subjectKey] = [$data['hashes'][$subjectKey]];

// Get indexes of all other elements with the same subject as the current one.
$duplicates = array_keys($data['subjects'], $subject);
$hashes = [];
array_shift($duplicates);

// Add hashes of duplicate subjects to the current subject and remove this duplicates.
// Subjects and hashes which belong to each other, have the same array key.
foreach ($duplicates as $key => $index) {
// Collect hashes.
if (!is_array($data['hashes'][$index])) {
$hashes[] = $data['hashes'][$index];
} else {
$hashes = $data['hashes'][$index];
}

$data['hashes'][$index] = $hashes;

// Remove all but last duplicate.
end($duplicates);
if ($key !== key($duplicates)) {
unset($data['subjects'][$index], $data['hashes'][$index]);
}
$data['hashes'][$subjectKey][] = $data['hashes'][$index];
unset($data['subjects'][$index], $data['hashes'][$index]);
}

// Remove subjects and hashes without specified labels.
Expand Down
24 changes: 15 additions & 9 deletions tests/GitChangeLogTest.php
Expand Up @@ -232,7 +232,7 @@ public function testSetFromTag()

public function testBuildAscendingCommitOrder()
{
$changeLog = new GitChangeLog();
$changeLog = new GitChangeLog();
$changeLog->setOptions('tagOrderDesc', false);
$testValues =
[
Expand Down Expand Up @@ -266,7 +266,7 @@ public function testBuildAscendingCommitOrder()

public function testBuildDescendingCommitOrder()
{
$changeLog = new GitChangeLog();
$changeLog = new GitChangeLog();
$changeLog->setOptions('commitOrder', 'DESC');
$testValues =
[
Expand Down Expand Up @@ -305,20 +305,26 @@ public function testProcessCommitData()
$method->setAccessible(true);

$changeLog = new GitChangeLog();
$changeLog->setLabels('C', 'D');
$changeLog->setLabels('C', 'D', 'F');

$value = ['A' => ['date' => 'B', 'subjects' => ['C', 'D', 'C', 'E'], 'hashes' => ['F', 'G', 'H', 'I']]];
$this->setPrivateProperty($changeLog, 'commitData', $value);
$value = [
$commitData = [
'A' => [
'date' => 'B',
'subjects' => [0 => 'C', 1 => 'D', 2 => 'C', 3 => 'E', 4 => 'F'],
'hashes' => [0 => 'G', 1 => 'H', 2 => 'I', 3 => 'J', 4 => 'K'],
],
];
$this->setPrivateProperty($changeLog, 'commitData', $commitData);
$commitData = [
'A' => [
'date' => 'B',
'subjects' => [1 => 'D', 2 => 'C'],
'hashes' => [1 => ['G'], 2 => ['F', 'H']],
'subjects' => [0 => 'C', 1 => 'D', 4 => 'F'],
'hashes' => [0 => ['G', 'I'], 1 => ['H'], 4 => ['K']],
],
];
$method->invokeArgs($changeLog, []);

$this->assertEquals($value, $this->getPrivateProperty($changeLog, 'commitData'));
$this->assertEquals($commitData, $this->getPrivateProperty($changeLog, 'commitData'));
}

public function testAddLabel()
Expand Down

0 comments on commit 6dc2bee

Please sign in to comment.