Passed
Push — 1.x ( 5b3b89...65c981 )
by Ulises Jeremias
02:37
created

Sort::heapSort()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php namespace Mbh\Collection\Traits;
2
3
/**
4
 * MBHFramework
5
 *
6
 * @link      https://github.com/MBHFramework/mbh-framework
7
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
8
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
9
 */
10
11
use Mbh\Collection\FixedArray;
12
use Mbh\Collection\Interfaces\Sequenceable as SequenceableInterface;
13
use Traversable;
14
use SplFixedArray;
15
use SplStack;
16
use LimitIterator;
17
18
trait Sort
19
{
20
    /**
21
     * Perform a bottom-up, non-recursive, in-place mergesort.
22
     * Efficient for very-large objects, and written without recursion
23
     * since PHP isn't well optimized for large recursion stacks.
24
     *
25
     * @param callable $callback The callback for comparison
26
     * @return SequenceableInterface
27
     */
28
    public function mergeSort(callable $callback): SequenceableInterface
29
    {
30
        $count = count($this);
0 ignored issues
show
Bug introduced by
$this of type Mbh\Collection\Traits\Sort is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

30
        $count = count(/** @scrutinizer ignore-type */ $this);
Loading history...
31
        $result = new SplFixedArray($count);
32
        for ($k = 1; $k < $count; $k = $k << 1) {
33
            for ($left = 0; ($left + $k) < $count; $left += $k << 1) {
34
                $right = $left + $k;
35
                $rend = min($right + $k, $count);
36
                $m = $left;
37
                $i = $left;
38
                $j = $right;
39
                while ($i < $right && $j < $rend) {
40
                    if ($callback($this[$i], $this[$j]) <= 0) {
41
                        $result[$m] = $this[$i];
42
                        $i++;
43
                    } else {
44
                        $result[$m] = $this[$j];
45
                        $j++;
46
                    }
47
                    $m++;
48
                }
49
                while ($i < $right) {
50
                    $result[$m] = $this[$i];
51
                    $i++;
52
                    $m++;
53
                }
54
                while ($j < $rend) {
55
                    $result[$m] = $this[$j];
56
                    $j++;
57
                    $m++;
58
                }
59
                for ($m = $left; $m < $rend; $m++) {
60
                    $this[$m] = $result[$m];
61
                }
62
            }
63
        }
64
65
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Mbh\Collection\Traits\Sort which is incompatible with the type-hinted return Mbh\Collection\Interfaces\Sequenceable.
Loading history...
66
    }
67
68
    /**
69
     * Sort by applying a CallbackHeap and building a new heap
70
     * Can be efficient for sorting large stored objects.
71
     *
72
     * @param callable $callback The comparison callback
73
     * @return SequenceableInterface
74
     */
75
    public function heapSort(callable $callback): SequenceableInterface
76
    {
77
        $this->setTraversable($this->heapSortedWithCallback($callback));
0 ignored issues
show
Bug introduced by
The method heapSortedWithCallback() does not exist on Mbh\Collection\Traits\Sort. Did you maybe mean heapSort()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

77
        $this->setTraversable($this->/** @scrutinizer ignore-call */ heapSortedWithCallback($callback));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
79
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Mbh\Collection\Traits\Sort which is incompatible with the type-hinted return Mbh\Collection\Interfaces\Sequenceable.
Loading history...
80
    }
81
82
    /**
83
     * Sort by applying a CallbackHeap and building a new heap
84
     * Can be efficient for sorting large stored objects.
85
     *
86
     * @param callable $callback The comparison callback
87
     * @return SequenceableInterface
88
     */
89
    public function heapSorted(callable $callback): SequenceableInterface
90
    {
91
        $h = new CallbackHeap($callback);
0 ignored issues
show
Bug introduced by
The type Mbh\Collection\Traits\CallbackHeap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
92
        foreach ($this as $elem) {
93
            $h->insert($elem);
94
        }
95
96
        return static::fromItems($h);
97
    }
98
99
    /**
100
     * Fallback behaviour to use the builtin array sort functions
101
     *
102
     * @param callable $callback The callback for comparison
103
     * @return SequenceableInterface
104
     */
105
    public function arraySort(callable $callback = null): SequenceableInterface
106
    {
107
        $array = $this->toArray();
0 ignored issues
show
Bug introduced by
It seems like toArray() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
        /** @scrutinizer ignore-call */ 
108
        $array = $this->toArray();
Loading history...
108
109
        if ($callback) {
110
            usort($array, $callback);
111
        } else {
112
            sort($array);
113
        }
114
115
        $this->setTraversable(static::fromArray($array));
116
117
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Mbh\Collection\Traits\Sort which is incompatible with the type-hinted return Mbh\Collection\Interfaces\Sequenceable.
Loading history...
118
    }
119
120
    abstract protected function setTraversable(Traversable $traversable);
121
}
122