• Stars
    star
    239
  • Rank 168,763 (Top 4 %)
  • Language
    PHP
  • License
    MIT License
  • Created about 10 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

High-Performance Topological Sort / Dependency resolver in PHP

Topological Sort / Dependency resolver in PHP

Build Status Code Climate Test Coverage

This library provides several implementations of a Topological Sort (topSort). In additional to the plain sorting algorithm it provides several implementations of a Grouped Topological Sort, means you can pass items with a type which will be grouped together in the sorting. With its implementation of using strings instead of arrays its over 20x faster than regular implementations.

What is it?

A topological sort is useful for determining dependency loading. It tells you which elements need to be proceeded first in order to fulfill all dependencies in the correct order.

Example usage: Unit of Work (relations), simple Package manager, Dependency Injection, ...

Examples:

$sorter = new StringSort();

$sorter->add('car1', ['owner1', 'brand1']);
$sorter->add('brand1');
$sorter->add('brand2');
$sorter->add('owner1', ['brand1']);
$sorter->add('owner2', ['brand2']);

$result = $sorter->sort();
// output would be:
[
 'brand1',
 'owner1',
 'car1',
 'brand2',
 'owner2'
]

Sometimes you want to group equal types together (imagine a UnitOfWork which wants to combine all elements from the same type to stored those in one batch):

$sorter = new GroupedStringSort();

$sorter->add('car1', 'car', ['owner1', 'brand1']);
$sorter->add('brand1', 'brand');
$sorter->add('brand2', 'brand');
$sorter->add('owner1', 'user', ['brand1']);
$sorter->add('owner2', 'user', ['brand2']);

$result = $sorter->sort();
// output would be:
[
 'brand2',
 'brand1',
 'owner2',
 'owner1',
 'car1'
]

$groups = $sorter->getGroups();
[
   {type: 'brand', level: 0, position: 0, length: 2},
   {type: 'user', level: 1, position: 2, length: 2},
   {type: 'car', level: 2, position: 4, length: 1},
]
//of course there may be several groups with the same type, if the dependency graphs makes this necessary.

foreach ($groups as $group) {
   $firstItem = $result[$group->position];
   $allItemsOfThisGroup = array_slice($result, $group->position, $group->length);
}

You can only store strings as elements. To sort PHP objects you can stored its hash instead. $sorter->add(spl_object_hash($obj1), [spl_object_hash($objt1Dep)]).

Installation

Use composer package: marcj/topsort

{
    "require": {
        "marcj/topsort": "~0.1"
    }
}
include 'vendor/autoload.php';

$sorter = new GroupedStringSort;
$sorter->add(...);

$result = $sorter->sort();

Implementations

tl;dr: Use FixedArraySort for normal topSort or GroupedStringSort for grouped topSort since its always the fastest and has a good memory footprint.

ArraySort

This is the most basic, most inefficient implementation of topSort using plain php arrays.

FixedArraySort

This uses \SplFixedArray of php and is therefore much more memory friendly.

StringSort

This uses a string as storage and has therefore no array overhead. It's thus a bit faster and has almost equal memory footprint like FixedArraySort. Small drawback: You can not store element ids containing a null byte.

GroupedArraySort

This is the most basic, not so efficient implementation of grouped topSort using plain php arrays.

GroupedStringSort

This uses a string as storage and has therefore no array operations overhead. It's extremely faster and has better memory footprint than GroupedArraySort. Small drawback: You can not store element ids containing a null byte.

Benchmarks with PHP 7.0.9

Test data: 1/3 has two edges, 1/3 has one edge and 1/3 has no edges. Use the benchmark command in ./bin/console to play with it.

Count Implementation Memory Duration
50 FixedArraySort 0b 0.0001s
50 ArraySort 0b 0.0001s
50 StringSort 0b 0.0001s
1,000 FixedArraySort 53,432b 0.0013s
1,000 ArraySort 37,720b 0.0012s
1,000 StringSort 89,112b 0.0013s
10,000 FixedArraySort 692,464b 0.0141s
10,000 ArraySort 529,240b 0.0138s
10,000 StringSort 1,080,472b 0.0154s
100,000 FixedArraySort 5,800,200b 0.1540s
100,000 ArraySort 4,199,280b 0.1499s
100,000 StringSort 10,124,000b 0.1645s
1,000,000 FixedArraySort 49,561,888b 1.5456s
1,000,000 ArraySort 33,559,408b 1.5597s
1,000,000 StringSort 95,480,848b 1.7942s
Count Implementation Memory Duration
50 GroupedArraySort 0b 0.0002s
50 GroupedStringSort 0b 0.0002s
1,000 GroupedArraySort 112,280b 0.0090s
1,000 GroupedStringSort 99,440b 0.0025s
10,000 GroupedArraySort 1,431,320b 0.8385s
10,000 GroupedStringSort 1,176,304b 0.0267s
100,000 GroupedArraySort 12,318,072b 132.9709s
100,000 GroupedStringSort 11,129,144b 0.2788s
1,000,000 GroupedArraySort - too long
1,000,000 GroupedStringSort 106,488,496b 3.0879s

More Repositories

1

css-element-queries

CSS Element-Queries aka Container Queries. High-speed element dimension/media queries in valid css.
JavaScript
4,273
star
2

TypeRunner

High-performance TypeScript compiler
C++
2,595
star
3

jquery-selectBox

A jQuery plugin for replacing <select> elements.
JavaScript
548
star
4

angular2-localstorage

Angular 2+ decorator to save and restore variables/class properties to HTML5 LocalStorage automatically.
TypeScript
302
star
5

php-rest-service

Php-Rest-Service is a very simple and fast PHP class for server-side RESTful JSON APIs.
PHP
216
star
6

BetterQuitJobBundle

You should better quit your current job instead of searching a solution for *that* problem.
95
star
7

Pesto

Pesto is a high-performance GUI framework in C++ highly inspired by CSS and HTML, using Skia as rendering engine.
C++
67
star
8

angular-es6-annotations

This little collection of annotations and registry functions allows you to register directives, controllers and filter with annotations at your angular module.
JavaScript
66
star
9

angular-desktop-ui

Angular & Electron desktop UI framework. Angular components for native looking and behaving macOS desktop UI (Electron/Web)
TypeScript
55
star
10

pybridge

TypeScript library to access python functions in NodeJS, type-safe and easy to use.
TypeScript
49
star
11

typescript-react-dependency-injection

React + Vite + Deepkit's powerful dependency injection system
TypeScript
30
star
12

typedoc-plugin-lerna-packages

A plugin for Typedoc that groups all Lerna packages into own TS module
TypeScript
28
star
13

npm-local-development

Replacement for 'npm link' that actually works. Automatically overwrites installed packages with a locally available dev version.
JavaScript
25
star
14

glut.ts

The first reactive full-stack framework for Typescript specially tailored for admin interfaces and complex SPA.
TypeScript
24
star
15

bitcoin.ts

Typescript implementation of a Cryptocurrency inspired by the Bitcoin blockchain.
TypeScript
22
star
16

chrome-chatgpt-screenshot-extension

JavaScript
12
star
17

google-api-php-client

Google APIs Client Library for PHP
PHP
11
star
18

krycms-bundle-old

Don't use it. Don't Star it. Old project. New Project is https://github.com/jarves/jarves |
JavaScript
10
star
19

angular-typescript-decorators

Kinda hackish handy decorators for using Typescript with Angular v1.4+
TypeScript
9
star
20

katana-orm

Katana ORM, the new incredible sharp PHP ORM - maybe someday.
8
star
21

typescript-semantic-search

TypeScript
5
star
22

angular-zoneless

Angular v16+ Zoneless implementation for SSR with Hydration
TypeScript
5
star
23

optimistic-locking-behavior

A behavior allowing you to use optimistic locking in Propel 2
PHP
5
star
24

twig-apply_filter-bundle

Symfony Bundle for Twig 'apply_filter' to call dynamic filters.
PHP
4
star
25

deepkit-bookstore

Example bookstore API with Deepkit API Console
TypeScript
3
star
26

angular-unsub

Unsubscribes automatically your RXJS subscriptions when component is ngOnDestroy'ed
TypeScript
3
star
27

change-logger-behavior

Logs changes for defined columns in a extra logger table, for Propel2
PHP
3
star
28

glut-admin

The first real-time headless CMS/CMF with crud builder, based on Typescript/Angular. So efficient and fast it hurts.
TypeScript
2
star
29

mootools-sprintf

Mootools Javascript sprintf/printf function.
JavaScript
2
star
30

estdlib.ts

Engineer's strict stdlib for TypeScript.
TypeScript
2
star
31

mowla.js

A fast and super simple JavaScript Template Engine.
JavaScript
1
star
32

shellfuncs

Some useful bash functions
Shell
1
star
33

deepkit-webpack

JavaScript
1
star
34

git-objects-sync

git push based on objects, instead of commits.
Python
1
star
35

Propel2-old

PHP
1
star
36

angular-ivy-issue1

TypeScript
1
star
37

vscode-vertical-tabs

1
star
38

shut-the-lock

iOs Game "Shut the lock"
JavaScript
1
star
39

docker-macOS-container

An easy way to run commands in docker using macOS catalina as OS (via qemu) via ssh. Jenkins node possible
Shell
1
star
40

angular-desktop-ui-example

Angular v9 with angular-desktop-ui configured and ready to use
TypeScript
1
star
41

docker-pytorch

Pytorch v2+ in docker with ARM support
Dockerfile
1
star
42

angular-marshal-example

TypeScript
1
star
43

ts-bug

JavaScript
1
star