{"id":16926747,"url":"https://github.com/kbknapp/violin","last_synced_at":"2025-03-22T11:31:06.903Z","repository":{"id":62444040,"uuid":"397388930","full_name":"kbknapp/violin","owner":"kbknapp","description":"A no_std no alloc implementation of the Vivaldi network coordinate system in Rust","archived":false,"fork":false,"pushed_at":"2023-06-20T01:19:12.000Z","size":112,"stargazers_count":23,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-18T10:51:35.431Z","etag":null,"topics":["coordinates","network","rust","vivaldi"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kbknapp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"kbknapp","patreon":"kbknapp"}},"created_at":"2021-08-17T20:55:24.000Z","updated_at":"2025-02-14T12:40:40.000Z","dependencies_parsed_at":"2024-10-28T13:17:16.474Z","dependency_job_id":"938b64ff-5019-4622-b3ad-fe5ad55b8f69","html_url":"https://github.com/kbknapp/violin","commit_stats":{"total_commits":61,"total_committers":1,"mean_commits":61.0,"dds":0.0,"last_synced_commit":"a7c98fddbd6e8f7452072f8025fbc3595b5efa3d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbknapp%2Fviolin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbknapp%2Fviolin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbknapp%2Fviolin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbknapp%2Fviolin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kbknapp","download_url":"https://codeload.github.com/kbknapp/violin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244951285,"owners_count":20537354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coordinates","network","rust","vivaldi"],"created_at":"2024-10-13T20:31:21.066Z","updated_at":"2025-03-22T11:31:06.495Z","avatar_url":"https://github.com/kbknapp.png","language":"Rust","readme":"# `violin`\n\n![Rust Version][rustc-image]\n[![crates.io][crate-image]][crate-link]\n[![Documentation][docs-image]][docs-link]\n[![Dependency Status][deps-image]][deps-link]\n\nA Rust `no_std` no `alloc` implementation of the [Vivaldi algorithm][1](PDF)\nfor a network coordinate system.\n\nA network coordinate system allows nodes to accurately estimate network\nlatencies by merely exchanging coordinates.\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n* [Violin - The Pitch](#violin---the-pitch)\n* [Violin - The Anti-Pitch](#violin---the-anti-pitch)\n* [Compile from Source](#compile-from-source)\n* [Usage](#usage)\n* [Benchmarks](#benchmarks)\n    * [Notes on `no_std` Performance](#notes-on-no_std-performance)\n* [License](#license)\n    * [Contribution](#contribution)\n* [Related Papers and Research](#related-papers-and-research)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n## Violin - The Pitch\n\nViolin is an implementation of Vivaldi network coordinates that works in\n`no_std` and no `alloc` environments. Each coordinate is small consisting of a\ndimensional vector made up of an array of `f64`s. The arrays use const\ngenerics, so they can be as small as a single f64 or large as one needs.\nAlthough above a certain dimension there are diminishing returns.\n\nNodes can measure real latencies between an origin node, or each-other to\nadjust their coordinates in space.\n\nThe real power comes from being able to calculate distance between a remote\ncoordinate without ever having done a real latency check. For example node `A`\nmeasures against node `Origin`, node `B` does the same. Then `A` can be given\nthe coordinates to `B` and accurately estimate the latency without ever having\nmeasured `B` directly.\n\n## Violin - The Anti-Pitch\n\nVivaldi isn't a magic bullet and still requires measuring real latencies to\nadjust the coordinates. In a naive implementation, conducting a latency check\nprior to a coordinate calculation is not much better than just using the\nlatency check directly as the answer. However, this is not how it's supposed to\nbe used.\n\nTransferring a Violin coordinate in practice can be comparable data to a small\nset of ICMP messages. For example an 8-Dimension coordinate (plus three\nadditional `f64`s of metadata) is 88 bytes. However, unlike ICMP messages, the\nViolin coordinates are a single transmission and only need to be re-transmitted\non significant change. Work could even be done to only transmit deltas as well.\n\n## Compile from Source\n\nEnsure you have a [Rust toolchain installed][rustup], and have cloned the repository locally.\n\n```sh\nRUSTFLAGS='-Ctarget-cpu=native' cargo build --release\n```\n\n**NOTE:** The `RUSTFLAGS` can be omitted. However, if on a recent CPU that\nsupports SIMD instructions, and the code will be run on the same CPU it's\ncompiled for, including this flag can improve performance.\n\n## Usage\n\nSee the `examples/` directory in this repository for complete details, although\nat quick glance creating three coordinates (`origin`, `a` and `b`) and updating\n`a` and `b`'s coordinate from experienced real latency would look like this:\n\n```rust\nuse std::time::Duration;\nuse violin::{heapless::VecD, Coord, Node};\n\n// Create two nodes and an \"origin\" coordinate, all using a 4-Dimensional\n// coordinate. `VecD` is a dimensional vector.\nlet origin = Coord::\u003cVecD\u003c4\u003e\u003e::rand();\nlet mut a = Node::\u003cVecD\u003c4\u003e\u003e::rand();\nlet mut b = Node::\u003cVecD\u003c4\u003e\u003e::rand();\n\n// **conduct some latency measurement from a to origin**\n// let's assume we observed a value of `0.2` seconds...\n//\n// **conduct some latency measurement from b to origin**\n// let's assume we observed a value of `0.03` seconds...\n\na.update(Duration::from_secs_f64(0.2), \u0026origin);\nb.update(Duration::from_secs_f64(0.03), \u0026origin);\n\n// Estimate from a to b even though we never measured them directly\nprintln!(\"a's estimate to b: {:.2}ms\", a.distance_to(\u0026b.coordinate()).as_millis());\n```\n\n## Benchmarks\n\nA set of benchmarks are included using 8D, 4D, and 2D coordinates both using\n`heap::VecD` (requires the `alloc` feature) and `heapless::VecD`.\n\nThe benchmarks measure both the higher level `Node` as well as a lower level\n`Coord` abstractions.\n\nTo measure we create 10,000 coordinates and the coordinates are\nupdate for each coordinate 100 times, totaling 1,000,000 updates.\n\nOn my 8 core AMD Ryzen 7 5850U laptop with 16GB RAM the benchmarks look as\nfollows:\n\n| Abstraction | Memory   | Dimensions | Time |\n| :-: | :-:      | :-:        | :-:  |\n| `Node` | heap     | 8          | 66.537 ms |\n| `Coord` | heap     | 8          | 55.402 ms |\n| `Node` | heapless | 8          | 24.997 ms |\n| `Coord` | heapless | 8          | 16.552 ms |\n| `Node` | heap     | 4          | 49.501 ms |\n| `Coord` | heap     | 4          | 39.163 ms |\n| `Node` | heapless | 4          | 16.795 ms |\n| `Coord` | heapless | 4          | 11.780 ms |\n| `Node` | heap     | 2          | 54.363 ms |\n| `Coord` | heap     | 2          | 46.001 ms |\n| `Node` | heapless | 2          | 13.181 ms |\n| `Coord` | heapless | 2          | 10.916 ms |\n\nTo run the benchmarks yourself use `RUSTFLAGS='-Ctarget-cpu=native' cargo bench`.\n\n### Notes on `no_std` Performance\n\nThe `no_std` version is _much_ slower because it cannot use platform intrinsics\nfor square roots, floating point rounding, etc. Instead these functions had to\nbe hand written.\n\nAdditionally, the `no_std` square root functions round up to 8 decimals of\nprecision.\n\nOne should realistically only use the `no_std` version when there is a good\nreason to do so, such as an embedded device that absolutely does not support\n`std`.\n\nA single Vivaldi calculation only requires one square root calculation per\ndistance estimate. So pragmatically, it should be rare where such a device is\n_also_ needing to calculate thousands of square root operations per second.\n\nBut I still hear you, how much slower you ask? Here is the same table (although\nonly `heapless::VecD`), still 1,000,000 updates:\n\n| Abstraction | Memory   | Dimensions | Time |\n| :-: | :-:      | :-:        | :-:  |\n| `Node` | heapless | 8          | 6.4303 s  |\n| `Coord` | heapless | 8          | 6.3707 s |\n| `Node` | heapless | 4          | 6.5513 s |\n| `Coord` | heapless | 4          | 6.4179 s |\n| `Node` | heapless | 2          |  6.5722 s|\n| `Coord` | heapless | 2          |  6.3005 s |\n\nAgain, it should be rare for a low power device to need to do\n1,000,000 updates rapidly and not have the ability to use `std`.\n\n## License\n\nThis crate is licensed under either of\n\n* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)\n* [MIT license](http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly note otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\n## Related Papers and Research\n\n* [Vivaldi - A Decentralized Network Coordinate System][1](PDF)\n* [Network Coordinates in the Wild][2](PDF)\n* [Towards Network Triangle Inequality Violation Aware Distributed Systems][3](PDF)\n* [On Suitability of Euclidean Embedding for Host-based Network Coordinate Systems][4](PDF)\n* [Practical, Distributed Network Coordinates][5](PDF)\n* [Armon Dadgar on Vivaldi: Decentralized Network Coordinate System][6](Video)\n\n[//]: # (badges)\n\n[rustc-image]: https://img.shields.io/badge/rustc-1.59+-blue.svg\n[crate-image]: https://img.shields.io/crates/v/violin.svg\n[crate-link]: https://crates.io/crates/violin\n[docs-image]: https://docs.rs/violin/badge.svg\n[docs-link]: https://docs.rs/violin\n[deps-image]: https://deps.rs/repo/github/kbknapp/violin/status.svg\n[deps-link]: https://deps.rs/repo/github/kbknapp/violin\n\n[//]: # (links)\n\n[rustup]: https://rustup.rs\n[1]: https://pdos.csail.mit.edu/papers/vivaldi:sigcomm/paper.pdf\n[2]: https://www.usenix.org/legacy/event/nsdi07/tech/full_papers/ledlie/ledlie.pdf\n[3]: https://www.cs.rice.edu/~eugeneng/papers/IMC07.pdf\n[4]: https://www-users.cse.umn.edu/~zhang089/Papers/Lee-Suitability-tonfinal.pdf\n[5]: http://www.news.cs.nyu.edu/~jinyang/pub/hotnets03.pdf\n[6]: https://youtu.be/AszPoJjWK9Q?t=1690\n","funding_links":["https://github.com/sponsors/kbknapp","https://patreon.com/kbknapp"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbknapp%2Fviolin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkbknapp%2Fviolin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbknapp%2Fviolin/lists"}