Skip to content

Commit 18f0f9a

Browse files
authored
Fix client speed (#4)
1 parent 84c46b7 commit 18f0f9a

File tree

2 files changed

+122
-40
lines changed

2 files changed

+122
-40
lines changed

src/Collections/RelatedUsersCollection.php

Lines changed: 89 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,54 +16,119 @@ public function __construct(array $initial = [])
1616
public function append(string $userId, string $relatedUserId): self
1717
{
1818
$this->appendTo($userId, $relatedUserId);
19-
$this->handleChilds((string)$userId, (string)$relatedUserId);
2019

21-
//updating child's
22-
foreach ($this->relatedUsers as $key => $childs) {
23-
foreach ($childs as $child) {
24-
$this->handleChilds((string) $key, (string) $child);
25-
}
20+
return $this;
21+
}
22+
23+
private function appendTo(string $userId, string $relatedUserId): void
24+
{
25+
if ($userId === $relatedUserId) {
26+
return ;
2627
}
2728

29+
$this->appendAppend($userId, $relatedUserId);
30+
$this->appendAppend($relatedUserId, $userId);
31+
}
32+
33+
private function appendAppend(string $userId, string $relatedUserId): self
34+
{
35+
$this->init($relatedUserId);
36+
$this->merge($relatedUserId, $this->getMergedChilds($userId, [$relatedUserId]));
37+
$this->addRelatedUser($relatedUserId, $userId);
38+
$this->unique($relatedUserId);
39+
$this->regenerateChilds($userId);
40+
2841
return $this;
2942
}
3043

31-
private function handleChilds(string $userId, string $relatedUserId): void
44+
private function regenerateChilds(string $userId): self
3245
{
33-
foreach ($this->relatedUsers[$userId] as $childId) {
34-
$this->appendTo((string) $childId, (string)$userId);
35-
$this->appendTo((string) $childId, (string) $relatedUserId);
46+
$childs = $this->relatedUsers[$userId] ?? []; // [a1, a2,a]
47+
foreach ($childs as $child) {
48+
$childChilds = $this->relatedUsers[$child]; // [a]
49+
$newChildChilds = $childChilds;
50+
foreach ($childChilds as $childChild) {
51+
$newChildChilds = array_unique(array_merge(
52+
$newChildChilds,
53+
$this->relatedUsers[$childChild]
54+
));
55+
}
56+
57+
$newChildChilds = array_filter($newChildChilds, function ($value) use ($child) {
58+
return $value !== $child;
59+
});
60+
61+
62+
$this->relatedUsers[$child] = array_unique($newChildChilds);
3663
}
64+
65+
66+
return $this;
3767
}
3868

39-
private function appendTo(string $userId, $relatedUserId): void
69+
private function addRelatedUser(string $dist, string $userId): self
4070
{
41-
if ($userId === $relatedUserId) {
42-
return ;
71+
$this->relatedUsers[$dist][] = $userId;
72+
return $this;
73+
}
74+
75+
private function merge(string $userId, array $value): self
76+
{
77+
$this->relatedUsers[$userId] = array_merge($this->relatedUsers[$userId], $value);
78+
return $this;
79+
}
80+
81+
private function init(string $userId): self
82+
{
83+
if (!isset($this->relatedUsers[$userId])) {
84+
$this->relatedUsers[$userId] = [];
4385
}
4486

45-
if (!isset($this->relatedUsers[$relatedUserId])) {
46-
$this->relatedUsers[$relatedUserId] = [$userId];
47-
} else {
48-
$this->relatedUsers[$relatedUserId][] = $userId;
49-
$this->relatedUsers[$relatedUserId] = array_unique($this->relatedUsers[$relatedUserId]);
87+
return $this;
88+
}
89+
90+
private function unique(string $userId): self
91+
{
92+
$this->relatedUsers[$userId] = array_unique($this->relatedUsers[$userId]);
93+
return $this;
94+
}
95+
96+
public function getMergedChilds(string $userId, array $except): array
97+
{
98+
$mergedChilds = [];
99+
$childs = $this->relatedUsers[$userId] ?? null;
100+
if ($childs === null) {
101+
return [];
50102
}
51103

52-
if (!isset($this->relatedUsers[$userId])) {
53-
$this->relatedUsers[$userId] = [$relatedUserId];
54-
} else {
55-
$this->relatedUsers[$userId][] = $relatedUserId;
56-
$this->relatedUsers[$userId] = array_unique($this->relatedUsers[$userId]);
104+
foreach ($childs as $child) {
105+
$mergedChilds[] = $child;
106+
$mergedChilds = array_merge($mergedChilds, $this->relatedUsers[$child] ?? []);
57107
}
108+
109+
$except[] = $userId;
110+
$mergedChilds = array_filter($mergedChilds, function ($value) use ($except) {
111+
return !in_array($value, $except);
112+
});
113+
114+
return $mergedChilds;
58115
}
59116

60117
public function getByUserId(string $userId): ?array
61118
{
62-
return $this->relatedUsers[$userId] ?? null;
119+
return array_values($this->relatedUsers[$userId]) ?? null;
63120
}
64121

65122
public function getAll(): array
66123
{
67124
return $this->relatedUsers;
68125
}
126+
127+
public function getAllApply($func): array
128+
{
129+
return array_map(function (array $val) use ($func) {
130+
$func($val);
131+
return $val;
132+
}, $this->relatedUsers);
133+
}
69134
}

tests/Unit/Collections/RelatedUsersCollectionTest.php

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,23 @@
99

1010
class RelatedUsersCollectionTest extends BaseTestCase
1111
{
12+
public function apply($func, array $arr): array
13+
{
14+
return array_map(function (array $val) use ($func) {
15+
$func($val);
16+
return $val;
17+
}, $arr);
18+
}
19+
1220
public function testAppendingWithSingleUser()
1321
{
1422
$collection = new RelatedUsersCollection();
1523
$collection->append('user', 'relatedUser');
1624

17-
$this->assertEquals($collection->getAll(), [
25+
$this->assertEquals($collection->getAllApply('sort'), $this->apply('sort', [
1826
'user' => ['relatedUser'],
1927
'relatedUser' => ['user'],
20-
]);
28+
]));
2129
}
2230

2331
public function testAppendingWithMultipleUsers()
@@ -27,12 +35,12 @@ public function testAppendingWithMultipleUsers()
2735
$collection->append('user', 'relatedUser2');
2836
$collection->append('user', 'relatedUser3');
2937

30-
$this->assertEquals($collection->getAll(), [
38+
$this->assertEquals($collection->getAllApply('sort'), $this->apply('sort', [
3139
'user' => ['relatedUser', 'relatedUser2', 'relatedUser3'],
3240
'relatedUser' => ['user', 'relatedUser2', 'relatedUser3'],
3341
'relatedUser2' => ['user', 'relatedUser', 'relatedUser3'],
3442
'relatedUser3' => ['user', 'relatedUser', 'relatedUser2'],
35-
]);
43+
]));
3644
}
3745

3846
public function testAppendingWithSameUsers()
@@ -47,12 +55,12 @@ public function testAppendingWithSameUsers()
4755
$collection->append('relatedUser2', 'relatedUser3');
4856
$collection->append('relatedUser3', 'relatedUser2');
4957

50-
$this->assertEquals($collection->getAll(), [
58+
$this->assertEquals($collection->getAllApply('sort'), $this->apply('sort', [
5159
'user' => ['relatedUser', 'relatedUser2', 'relatedUser3'],
5260
'relatedUser' => ['user', 'relatedUser2', 'relatedUser3'],
5361
'relatedUser2' => ['user', 'relatedUser', 'relatedUser3'],
5462
'relatedUser3' => ['user', 'relatedUser', 'relatedUser2'],
55-
]);
63+
]));
5664
}
5765

5866
public function testAppendingViaChilds()
@@ -63,12 +71,12 @@ public function testAppendingViaChilds()
6371
$collection->append('relatedUser2', 'user');
6472
$collection->append('relatedUser3', 'user');
6573

66-
$this->assertEquals($collection->getAll(), [
74+
$this->assertEquals($collection->getAllApply('sort'), $this->apply('sort', [
6775
'user' => ['relatedUser', 'relatedUser2', 'relatedUser3'],
6876
'relatedUser' => ['user', 'relatedUser2', 'relatedUser3'],
6977
'relatedUser2' => ['user', 'relatedUser', 'relatedUser3'],
7078
'relatedUser3' => ['user', 'relatedUser', 'relatedUser2'],
71-
]);
79+
]));
7280
}
7381

7482
public function testGettingForAppendingViaChilds()
@@ -89,14 +97,23 @@ public function testGettingForAppendingViaChilds()
8997
['user', 'relatedUser2', 'relatedUser3']
9098
);
9199

100+
$exp = ['user', 'relatedUser', 'relatedUser3'];
101+
sort($exp);
102+
$val = $collection->getByUserId('relatedUser2');
103+
sort($val);
92104
$this->assertEquals(
93-
$collection->getByUserId('relatedUser2'),
94-
['user', 'relatedUser', 'relatedUser3'],
105+
$val,
106+
$exp
95107
);
96108

109+
$val = $collection->getByUserId('relatedUser3');
110+
$exp = ['user', 'relatedUser', 'relatedUser2'];
111+
sort($val);
112+
sort($exp);
113+
97114
$this->assertEquals(
98-
$collection->getByUserId('relatedUser3'),
99-
['user', 'relatedUser', 'relatedUser2']
115+
$val,
116+
$exp
100117
);
101118
}
102119

@@ -112,7 +129,7 @@ public function testAppendingWithParallelRelatedUsers()
112129
$collection->append('user2', 'user2Related2');
113130
$collection->append('user2', 'user2Related3');
114131

115-
$this->assertEquals($collection->getAll(), [
132+
$this->assertEquals($collection->getAllApply('sort'), $this->apply('sort', [
116133
'user' => ['relatedUser', 'relatedUser2', 'relatedUser3'],
117134
'relatedUser' => ['user', 'relatedUser2', 'relatedUser3'],
118135
'relatedUser2' => ['user', 'relatedUser', 'relatedUser3'],
@@ -122,7 +139,7 @@ public function testAppendingWithParallelRelatedUsers()
122139
'user2Related' => ['user2', 'user2Related2', 'user2Related3'],
123140
'user2Related2' => ['user2', 'user2Related', 'user2Related3'],
124141
'user2Related3' => ['user2', 'user2Related', 'user2Related2'],
125-
]);
142+
]));
126143
}
127144

128145
public function testAppendingWithParallelRelatedUsersMerge()
@@ -140,7 +157,7 @@ public function testAppendingWithParallelRelatedUsersMerge()
140157
$collection->append('user', 'user2');
141158

142159

143-
$this->assertEquals($collection->getAll(), [
160+
$this->assertEquals($collection->getAllApply('sort'), $this->apply('sort', [
144161
'user' => [
145162
'relatedUser',
146163
'relatedUser2',
@@ -214,7 +231,7 @@ public function testAppendingWithParallelRelatedUsersMerge()
214231
'relatedUser2',
215232
'relatedUser3',
216233
],
217-
]);
234+
]));
218235
}
219236

220237
public function testAppendingWithParallelRelatedUsersMergeDirection2()

0 commit comments

Comments
 (0)