Skip to content

Commit

Permalink
Finalize 0.2.0 API
Browse files Browse the repository at this point in the history
Renamed some structs, traits and variants.
Fixed storage and dropping issues.
Fully implemented ptr_metadata support.
Cleaned up type interface to be more convenient.
Added support for mutation of stored data.
Separated library into more modules.
Improved tests.
Improved CI script and switch it to nightly

Signed-off-by: Tin Švagelj <tin.svagelj@live.com>
  • Loading branch information
Caellian committed Aug 29, 2023
1 parent 9f8e291 commit d6365de
Show file tree
Hide file tree
Showing 12 changed files with 719 additions and 376 deletions.
22 changes: 14 additions & 8 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@ name: Rust

on:
push:
branches: [ "trunk" ]
pull_request:
branches: [ "trunk" ]

env:
CARGO_TERM_COLOR: always

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- uses: actions/checkout@v3
- run: rustup update nightly && rustup default nightly
- name: Build default
run: cargo build --verbose
- name: Build no_std
run: cargo build --verbose --no-default-features --features no_std
- name: Build no_std with error_in_core
run: cargo build --verbose --no-default-features --features no_std,error_in_core
- name: Build with ptr_metadata
run: cargo build --verbose --features ptr_metadata
- name: Build restrictive
run: cargo build --verbose --no-default-features --features std
- name: Run tests
run: cargo test --verbose --features ptr_metadata
64 changes: 64 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'contiguous-mem'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=contiguous-mem"
],
"filter": {
"name": "contiguous-mem",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug example 'ptr_metadata'",
"cargo": {
"args": [
"build",
"--example=ptr_metadata",
"--package=contiguous-mem"
],
"filter": {
"name": "ptr_metadata",
"kind": "example"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in example 'ptr_metadata'",
"cargo": {
"args": [
"test",
"--no-run",
"--example=ptr_metadata",
"--package=contiguous-mem"
],
"filter": {
"name": "ptr_metadata",
"kind": "example"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ categories = [
]
repository = "https://github.com/Caellian/contiguous_mem"

[[example]]
name = "ptr_metadata"
path = "examples/ptr_metadata.rs"
required-features = ["ptr_metadata"]

[dependencies]
portable-atomic = { version = "1", default-features = false }
spin = { version = "0.9", optional = true }

[features]
default = ["std"]
default = ["std", "leak_data"]
std = ["portable-atomic/std"]
no_std = ["dep:spin"]
debug = []
leak_data = []
ptr_metadata = []
error_in_core = []
61 changes: 39 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,42 @@

contiguous_mem implements a contiguous memory storage container for arbitrary data types.

[![CI](https://github.com/Caellian/contiguous_mem/actions/workflows/rust.yml/badge.svg)](https://github.com/Caellian/contiguous_mem/actions/workflows/rust.yml)
[![Crates.io](https://img.shields.io/crates/v/contiguous_mem)](https://crates.io/crates/contiguous_mem)
[![Documentation](https://docs.rs/contiguous_mem/badge.svg)](https://docs.rs/contiguous_mem)

Designed for both standard and no_std environments, this library ensures efficient memory allocation while being simple and (somewhat) safe to use.
Designed for both standard and no_std environments, this library ensures efficient memory
allocation while being simple and (somewhat) safe to use.

## Tradeoffs

- Works without nightly but leaks data, enable `ptr_metadata` or disable default `leak_data`
feature flag if memory leaks are an issue:

- `ptr_metadata` requires nightly,
- disabling `leak_data` imposes `Copy` requirement on stored types.

- References returned by `store` function follow the same borrow restrictions as the
language, `Deref` is implemented for `ContiguousMemoryRef` but it will panic on
dereference if it's been already mutably borrowed somewhere else.
Use `ContiguousMemoryRef::try_get` if you'd like to handle that properly.

## Key Features

- Type Agnostic: Support for various data types, including mixed types within the same container.

- Multiple Implementations: Choose from specialized strategies to match your requirements:
- SyncContiguousMemory (ThreadSafeImpl): Enables asynchronous data access, ensuring safety in concurrent scenarios.
- GrowableContiguousMemory (NotThreadSafeImpl): Synchronous, mutex-free implementation for speed and dynamic resizing.
- FixedContiguousMemory (FixedSizeImpl): Highly optimized but unsafe for precise sizing and long-lived references.
- SyncContiguousMemory (ImplConcurrent): Enables asynchronous data access, ensuring safety in concurrent scenarios.
- GrowableContiguousMemory (ImplDefault): Synchronous, mutex-free implementation for speed and dynamic resizing.
- FixedContiguousMemory (ImplFixed): Highly optimized but unsafe for precise sizing and long-lived references.

## Getting Started

Add the crate to your dependencies:

```toml
[dependencies]
contiguous_mem = "0.2.*"
contiguous_mem = { version = "0.2.*" }
```

Optionally disable the `std` feature and enable `no_std` feature to use in `no_std` environment:
Expand All @@ -32,7 +47,19 @@ Optionally disable the `std` feature and enable `no_std` feature to use in `no_s
contiguous_mem = { version = "0.2.*", default-features = false, features = ["no_std"] }
```

### Example usage
### Features

- `std` (**default**) - enables support for `std` environment
- `no_std` - enables support for `no_std` environment
- `leak_data` (**default**) - disables `Copy` requirement for stored types, but any
references in stored data will be leaked when the memory container is dropped
- `debug` - enables `derive(Debug)` on structures unrelated to error handling
- `ptr_metadata` &lt;_nightly_&gt; - enables support for casting returned references
into `dyn Trait` types as well as cleaning up any types that implement `Drop`
or generate drop glue
- `error_in_core` &lt;_nightly_&gt; - enables support for `core::error::Error` in `no_std` environment

### Usage

```rust
use contiguous_mem::GrowableContiguousMemory;
Expand All @@ -42,30 +69,20 @@ struct Data {
}

fn main() {
// Create a ContiguousMemory instance with a capacity of 1024 bytes and 8-byte alignment
let mut memory = GrowableContiguousMemory::new(1024, 8).unwrap();
// Create a ContiguousMemory instance with a capacity of 1024 bytes and 1-byte alignment
let mut memory = GrowableContiguousMemory::new(1024);

// Store data in the memory container
let data = Data { value: 42 };
let stored_number = memory.store(22u64).unwrap();
let stored_data = memory.store(data).unwrap();
let stored_number = memory.store(22u64);
let stored_data = memory.store(data);

// Retrieve and use the stored data
let retrieved_data = stored_data.get().unwrap();
println!("Retrieved data: {}", retrieved_data.value);
let retrieved_number = stored_number.get().unwrap();
println!("Retrieved number: {}", retrieved_number);
println!("Retrieved data: {}", *stored_data);
println!("Retrieved number: {}", *stored_number);
}
```

### Features

- `std` (default) - enables support for `std` environment
- `no_std` - enables support for `no_std` environment
- `debug` - enables `derive(Debug)` on structures
- `ptr_metadata` - enables support for casting returned references into `dyn Trait` types
- `error_in_core` - enables support for `core::error::Error` in `no_std` environment

## Contributions

Contributions are welcome, feel free to create an issue or a pull request.
Expand Down
40 changes: 40 additions & 0 deletions examples/ptr_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![feature(ptr_metadata)]

use contiguous_mem::{
ptr_metadata_ext::static_metadata, ContiguousMemoryRef, GrowableContiguousMemory,
};

trait Greetable {
fn print_hello(&self);
}

struct Person(String);
impl Greetable for Person {
fn print_hello(&self) {
println!("Saying hello to person: {}", self.0);
}
}

struct Dog(String);
impl Greetable for Dog {
fn print_hello(&self) {
println!("Saying hello to dog: {}", self.0);
}
}

fn main() {
let mut storage = GrowableContiguousMemory::new(4096);
let person1 = storage.store(Person("Joe".to_string()));

let person2: ContiguousMemoryRef<dyn Greetable> = storage
.store(Person("Craig".to_string()))
.as_dyn(static_metadata::<Person, dyn Greetable>());

let dog: ContiguousMemoryRef<dyn Greetable> = storage
.store(Dog("Rover".to_string()))
.as_dyn(static_metadata::<Dog, dyn Greetable>());

person1.print_hello();
person2.print_hello();
dog.print_hello();
}
38 changes: 0 additions & 38 deletions examples/traits.rs

This file was deleted.

Loading

0 comments on commit d6365de

Please sign in to comment.