{"id":17537765,"url":"https://github.com/lthibault/uq","last_synced_at":"2025-03-29T03:46:26.730Z","repository":{"id":62973645,"uuid":"563900262","full_name":"lthibault/uq","owner":"lthibault","description":"Fast unbounded queue with efficient allocation","archived":false,"fork":false,"pushed_at":"2022-11-30T17:50:23.000Z","size":11,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-03T13:45:10.353Z","etag":null,"topics":["data-structures","generic","memory-efficient","queue"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lthibault.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-11-09T15:16:09.000Z","updated_at":"2022-11-09T15:36:43.000Z","dependencies_parsed_at":"2023-01-22T12:15:14.054Z","dependency_job_id":null,"html_url":"https://github.com/lthibault/uq","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lthibault%2Fuq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lthibault%2Fuq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lthibault%2Fuq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lthibault%2Fuq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lthibault","download_url":"https://codeload.github.com/lthibault/uq/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246135739,"owners_count":20729056,"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":["data-structures","generic","memory-efficient","queue"],"created_at":"2024-10-20T20:42:46.233Z","updated_at":"2025-03-29T03:46:26.709Z","avatar_url":"https://github.com/lthibault.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# uq\n\n[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/lthibault/uq)\n[![Go Report Card](https://goreportcard.com/badge/github.com/lthibault/uq?style=flat-square)](https://goreportcard.com/report/github.com/lthibault/uq)\n[![tests](https://github.com/lthibault/uq/workflows/Go/badge.svg)](https://github.com/lthibault/uq/actions/workflows/go.yml)\n\n\nFast unbounded queue with O(1) amortized allocations.\n\n\u003e**WARNING:**  use caution with unbounded memory.  Use appropriate flow-control measures to prevent OOM failures.\n\n## Benchmarks\n\nBelow are some benchmarks for the `Push` and `Shift` operations.  Benchmarks are notoriously difficult to interpret,\nbut these suggest that `uq.Queue` will not be a bottleneck in most applications.\n\nThe queue is implemented as a linked list of ring buffers, of geometrically-increasing capacity (r=2).  Moreover, when the queue is emptied, the final ring buffer is not released, so that a subsequen call to `Push` does not immediately allocate a new one.  These optimizations result in amortized constant-time allocations.  Effectively, `uq` converges on the appropriate size for a single ring-buffer for any constant workload.\n\nA geometric growth factor of `r=2` is required to ensure ring buffer capacities are always powers of 2.  On average, this means about 40% of the largest ring buffer is empty.  To mitigate this waste, the ring buffer size is correspondingly shrunk when the queue is empty.  Note that pathological workloads exist, which may either prevent an under-utilized buffer from being downsized or cause thrashing.  Both issues can be mitigated by implementing appropriate flow-control mechanisms to smooth out dataflow.  Future work should focus on refactoring the ring buffers to support arbitrary capacities, at which point we can set the growth rate to a more conservative `r=1.5` and the shrink rate to an asymmetrical value of `r=.25`.\n\n```\n$ go test -benchmem -run='^$' -bench '^BenchmarkQueue$' github.com/lthibault/uq\ngoos: darwin\ngoarch: amd64\npkg: github.com/lthibault/uq\ncpu: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz\nBenchmarkQueue/Push-8           197861551                7.076 ns/op          10 B/op          0 allocs/op\nBenchmarkQueue/Shift-8          262964143                4.545 ns/op           0 B/op          0 allocs/op\nPASS\nok      github.com/lthibault/uq 6.805s\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flthibault%2Fuq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flthibault%2Fuq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flthibault%2Fuq/lists"}