{"id":25463109,"url":"https://github.com/jaksa-krawczyk/brbuffer","last_synced_at":"2025-11-03T20:30:29.847Z","repository":{"id":277592368,"uuid":"932908128","full_name":"jaksa-krawczyk/brbuffer","owner":"jaksa-krawczyk","description":"Lockless ring buffer","archived":false,"fork":false,"pushed_at":"2025-02-14T19:06:05.000Z","size":4,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-14T20:18:47.703Z","etag":null,"topics":["cpp17","lockless","multiple-producers","ring-buffer","single-consumer"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaksa-krawczyk.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-14T18:38:20.000Z","updated_at":"2025-02-14T19:06:54.000Z","dependencies_parsed_at":"2025-02-14T20:18:49.699Z","dependency_job_id":"ee890426-1066-4577-bd04-d27168458ed3","html_url":"https://github.com/jaksa-krawczyk/brbuffer","commit_stats":null,"previous_names":["jaksa-krawczyk/brbuffer"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaksa-krawczyk%2Fbrbuffer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaksa-krawczyk%2Fbrbuffer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaksa-krawczyk%2Fbrbuffer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaksa-krawczyk%2Fbrbuffer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaksa-krawczyk","download_url":"https://codeload.github.com/jaksa-krawczyk/brbuffer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239418577,"owners_count":19635208,"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":["cpp17","lockless","multiple-producers","ring-buffer","single-consumer"],"created_at":"2025-02-18T06:19:34.998Z","updated_at":"2025-11-03T20:30:29.800Z","avatar_url":"https://github.com/jaksa-krawczyk.png","language":"C++","readme":"# Lockless bucket ring buffer\nLock free ring buffer that stores data in buckets of constant size. It supports multiple producers but only one consumer. Suitable for use when data stored in the buffer does not vary much in size. Written in C++17 standard.\n## Usage\n- `BRingBuffer\u003ccapacity, maxDataSize\u003e buffer;` - creates a buffer with a number `capacity` of buckets and each bucket can contain data of `maxDataSize` size.\n- `void* reserve(const std::uint32_t dataSize)` - reserves data in buffer, returns pointer to the appropriate bucket where user data can be stored. Returns `nullptr` if buffer is full.\n- `void commit(void* const dataPtr)` - commits previously reserved data, after this call data is ready to be read by the consumer.\n- `void* peek(std::uint32_t\u0026 dataSize, const std::uint64_t magicId)` - checks if there is data ready to consume, returns `nullptr` if the buffer is empty. The size of the data is put into `dataSize` for the user. `magicId` should be initially set to `0` by the caller and must not be changed by the caller in the future. This allowed to remove one atomic load operation.\n- `void decommit(void* const dataPtr, std::uint64_t\u0026 magicId)` - marks the bucket to be available to the producers. `magicId` is changed internally and should be passed to the next `peek()` call.\n## The algorithm\n1. The producers cannot exceed the consumer.\n2. The consumer advances from one bucket to the next and checks if data is available. Data is consumed sequentially.\n3. Both the producers and consumer keep the track of wrap around count to prevent producers from exceeding the consumer.\n\nFor the most optimistic case there are two atomic loads, one CAS operation and one atomic store for a producer.\n\nThere is always one atomic load and two atomic stores for the consumer.\n## TO DO\nPerformance and stability tests.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaksa-krawczyk%2Fbrbuffer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaksa-krawczyk%2Fbrbuffer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaksa-krawczyk%2Fbrbuffer/lists"}