Single-header • Type-safe • Memory-safe • Anti-DoS • Zero dependencies
Features • Quick Start • Examples • Performance • Security • Documentation
NanoDS v1.0.0 is the production-ready release that brings enterprise-grade security, advanced data structures, and universal APIs to C programming.
// Unsafe, manual memory management
int* arr = malloc(10 * sizeof(int));
// No bounds checking
arr[100] = 42; // 💥 Crash!
// Memory leaks everywhere
// Type casting nightmares
void* map = create_map();
int val = *(int*)get(map, "key"); |
#define NANODS_IMPLEMENTATION
#include "nanods.h"
IntVector vec;
nv_init_int(&vec);
nv_push_int(&vec, 42); // ✓ Safe
int val;
nv_get_int(&vec, 0, &val); // ✓ Type-safe
nv_free_int(&vec); // ✓ No leaks |
| Feature | Description | Impact |
|---|---|---|
| 🔐 Anti-DoS Security | Randomized hash seeding | Prevents hash-flooding attacks |
| 📦 Doubly Linked Lists | Bidirectional traversal | O(1) insertions anywhere |
| ⭕ Ring Buffers | Fixed-size circular buffers | Zero heap, perfect for embedded |
| 🔄 Universal Iterators | Unified traversal API | Consistent across all containers |
| 🛡️ Secure Flags | Automatic memory wiping | Protects sensitive data |
| ⚡ Compiler Hints | likely/unlikely optimizations |
5-10% performance boost |
nanods_seed_init(0); // Auto-generate seed
NanoMap map;
nm_init(&map);
printf("Seed: 0x%08X\n", map.seed);
// Different every run → DoS resistantProtects against:
|
IntVector passwords;
nv_init_ex_int(&passwords,
NANODS_FLAG_SECURE);
// ... store passwords ...
nv_free_int(&passwords);
// Memory automatically zeroed! Use cases:
|
All operations optimized with compiler hints (__builtin_expect):
| Operation | Throughput | Latency | Complexity |
|---|---|---|---|
| Vector Push | 340M ops/sec | 0.003 µs | O(1) amortized |
| Stack Push/Pop | 920M ops/sec | 0.001 µs | O(1) |
| List Push | 53M ops/sec | 0.019 µs | O(1) |
| List2 Push | 48M ops/sec | 0.021 µs | O(1) |
| Ring Write/Read | 1.2B ops/sec | 0.0008 µs | O(1) |
| Map Set/Get | 500K ops/sec | 1.983 µs | O(1) average |
Benchmarked on Intel i7-10700K @ 3.8GHz, GCC -O3
| Data Structure | Operation | Best | Average | Worst | Space |
|---|---|---|---|---|---|
| Vector | push | O(1) | O(1)* | O(n) | O(n) |
| pop | O(1) | O(1) | O(1) | ||
| get/set | O(1) | O(1) | O(1) | ||
| reserve | O(n) | O(n) | O(n) | ||
| map | O(n) | O(n) | O(n) | ||
| filter | O(n) | O(n) | O(n) | ||
| Stack | push | O(1) | O(1)* | O(n) | O(n) |
| pop | O(1) | O(1) | O(1) | ||
| peek | O(1) | O(1) | O(1) | ||
| List | push_front | O(1) | O(1) | O(1) | O(n) |
| push_back | O(1) | O(1) | O(1) | ||
| pop_front | O(1) | O(1) | O(1) | ||
| List2 🆕 | push_front | O(1) | O(1) | O(1) | O(n) |
| push_back | O(1) | O(1) | O(1) | ||
| pop_front | O(1) | O(1) | O(1) | ||
| pop_back | O(1) | O(1) | O(1) | ||
| insert_after | O(1) | O(1) | O(1) | ||
| remove_node | O(1) | O(1) | O(1) | ||
| Ring 🆕 | write | O(1) | O(1) | O(1) | O(capacity) |
| read | O(1) | O(1) | O(1) | ||
| peek | O(1) | O(1) | O(1) | ||
| Map | set | O(1) | O(1) | O(n)** | O(n + b) |
| get | O(1) | O(1) | O(n)** | ||
| remove | O(1) | O(1) | O(n)** | ||
| has | O(1) | O(1) | O(n)** |
* Amortized with exponential growth (2x)
** O(n) only if all keys collide (prevented by randomized hashing)
| Structure | Description | New in v1.0.0 | Use Case |
|---|---|---|---|
| NanoVector | Dynamic array | ✓ Secure flag | Collections, sequential data |
| NanoStack | LIFO stack | ✓ Secure flag | Undo/redo, parsing |
| NanoList | Singly linked list | ✓ Secure flag | Frequent insertions |
| NanoList2 🆕 | Doubly linked list | 🆕 NEW | Bidirectional traversal |
| NanoRing 🆕 | Circular buffer | 🆕 NEW | Real-time streaming |
| NanoMap | Hash map | 🆕 Anti-DoS seed | Key-value storage |
Option 1: Direct Download
wget https://raw.githubusercontent.com/Nowazish-Nur-Kayef/NanoDS/main/nanods.hOption 2: Clone Repository
git clone https://github.com/Nowazish-Nur-Kayef/NanoDS.git
cd NanoDS
make run # Build and run testsOption 3: CMake Integration
include(FetchContent)
FetchContent_Declare(
nanods
GIT_REPOSITORY https://github.com/Nowazish-Nur-Kayef/NanoDS.git
GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(nanods)
target_link_libraries(myapp PRIVATE nanods)Click to expand - Bidirectional navigation
#define NANODS_IMPLEMENTATION
#include "nanods.h"
#include <stdio.h>
int main(void) {
IntList2 list;
nl2_init_int(&list);
// Add elements
nl2_push_back_int(&list, 10);
nl2_push_back_int(&list, 20);
nl2_push_back_int(&list, 30);
// Remove from both ends
int front, back;
nl2_pop_front_int(&list, &front); // front = 10
nl2_pop_back_int(&list, &back); // back = 30
printf("Remaining: %d\n", front); // 20
nl2_free_int(&list);
return 0;
}Output:
Remaining: 20
Advantages over singly-linked:
- ✅ O(1) removal from back
- ✅ Bidirectional traversal
- ✅ Easier node manipulation
Click to expand - Zero heap allocation, perfect for embedded
#define NANODS_IMPLEMENTATION
#include "nanods.h"
#include <stdio.h>
typedef struct {
float temperature;
float humidity;
int timestamp;
} SensorReading;
NANODS_DEFINE_RING(SensorReading, 16)
int main(void) {
NanoRing_SensorReading_16 ring;
nr_init_SensorReading_16(&ring);
// Simulate sensor readings
for (int i = 0; i < 20; i++) {
SensorReading reading = {
.temperature = 20.0f + i,
.humidity = 50.0f + i,
.timestamp = 1000 + i
};
if (nr_is_full_SensorReading_16(&ring)) {
// Overwrite oldest data (circular behavior)
SensorReading old;
nr_read_SensorReading_16(&ring, &old);
}
nr_write_SensorReading_16(&ring, reading);
}
// Read all data
printf("Recent readings:\n");
while (! nr_is_empty_SensorReading_16(&ring)) {
SensorReading r;
nr_read_SensorReading_16(&ring, &r);
printf("T=%d: %. 1f°C, %. 1f%%\n",
r.timestamp, r.temperature, r.humidity);
}
return 0;
}Output:
Recent readings:
T=1004: 24.0°C, 54.0%
T=1005: 25.0°C, 55.0%
...
T=1019: 39.0°C, 69.0%
Perfect for:
- ✅ Real-time audio/video buffers
- ✅ Embedded systems (no malloc)
- ✅ Producer-consumer queues
- ✅ Fixed-size history
Click to expand - Automatic memory wiping
#define NANODS_IMPLEMENTATION
#include "nanods.h"
#include <stdio.h>
#include <string.h>
int main(void) {
// Initialize with secure flag
CharVector password;
nv_init_ex_char(&password, NANODS_FLAG_SECURE);
// Store password
const char* pw = "SuperSecret123!";
for (size_t i = 0; i < strlen(pw); i++) {
nv_push_char(&password, pw[i]);
}
printf("Password stored securely\n");
printf("Size: %zu bytes\n", nv_size_char(&password));
// When freed, memory is automatically zeroed
nv_free_char(&password);
printf("✓ Memory securely wiped\n");
return 0;
}Output:
Password stored securely
Size: 15 bytes
✓ Memory securely wiped
Security guarantee:
- ✅ Memory is
memset(0)beforefree() - ✅ No sensitive data in freed memory
- ✅ Protects against memory dump attacks
Click to expand - Unified API across all containers
#define NANODS_IMPLEMENTATION
#include "nanods.h"
#include <stdio.h>
int main(void) {
// Create vector
IntVector vec;
nv_init_int(&vec);
for (int i = 1; i <= 5; i++) {
nv_push_int(&vec, i * 10);
}
// Iterate with universal iterator
printf("Vector: ");
NanoIter it = nv_iter_int(&vec);
while (!it.finished) {
int* val = (int*)it.ptr;
printf("%d ", *val);
nv_iter_next_int(&it);
}
printf("\n");
// Create doubly linked list
IntList2 list;
nl2_init_int(&list);
for (int i = 1; i <= 5; i++) {
nl2_push_back_int(&list, i * 100);
}
// Same iterator pattern!
printf("List2: ");
NanoIter it2 = nl2_iter_int(&list);
while (!it2.finished) {
int* val = (int*)it2.ptr;
printf("%d ", *val);
nl2_iter_next_int(&it2);
}
printf("\n");
nv_free_int(&vec);
nl2_free_int(&list);
return 0;
}Output:
Vector: 10 20 30 40 50
List2: 100 200 300 400 500
Benefits:
- ✅ Consistent API across all containers
- ✅ Easy to switch between data structures
- ✅ Familiar iteration pattern
Click to expand - Randomized seeding prevents attacks
#define NANODS_IMPLEMENTATION
#include "nanods.h"
#include <stdio.h>
int main(void) {
// Initialize random seed (call once at startup)
nanods_seed_init(0);
printf("Global seed: 0x%08X\n", nanods_get_seed());
// Create map (automatically uses randomized seed)
NanoMap map;
nm_init(&map);
printf("Map seed: 0x%08X (Anti-DoS enabled)\n\n", map.seed);
// Store data
int scores[] = {100, 200, 300};
nm_set(&map, "alice", &scores[0]);
nm_set(&map, "bob", &scores[1]);
nm_set(&map, "charlie", &scores[2]);
// Retrieve data
int* score = (int*)nm_get(&map, "bob");
printf("Bob's score: %d\n", score ? *score : -1);
nm_free(&map);
return 0;
}Output:
Global seed: 0x8A3F2C1D
Map seed: 0x8A3F2C1D (Anti-DoS enabled)
Bob's score: 200
Security:
- ✅ Seed changes every program run
- ✅ Attacker cannot predict collisions
- ✅ Prevents hash-flooding DoS attacks
- ✅ Used by Python, Ruby, Java
Click to expand - Map and filter operations
#define NANODS_IMPLEMENTATION
#include "nanods. h"
#include <stdio. h>
int double_value(int x) { return x * 2; }
int is_even(int x) { return x % 2 == 0; }
int main(void) {
IntVector numbers;
nv_init_int(&numbers);
for (int i = 1; i <= 10; i++) {
nv_push_int(&numbers, i);
}
// Map: transform every element
IntVector doubled;
nv_map_int(&numbers, &doubled, double_value);
printf("Doubled: ");
for (size_t i = 0; i < nv_size_int(&doubled); i++) {
int val;
nv_get_int(&doubled, i, &val);
printf("%d ", val);
}
printf("\n");
// Filter: select elements by predicate
IntVector evens;
nv_filter_int(&numbers, &evens, is_even);
printf("Evens: ");
for (size_t i = 0; i < nv_size_int(&evens); i++) {
int val;
nv_get_int(&evens, i, &val);
printf("%d ", val);
}
printf("\n");
nv_free_int(&numbers);
nv_free_int(&doubled);
nv_free_int(&evens);
return 0;
}Output:
Doubled: 2 4 6 8 10 12 14 16 18 20
Evens: 2 4 6 8 10
Program Start
↓
nanods_seed_init(0)
↓
Seed = time() ^ address_space
↓
Every NanoMap uses this seed
↓
Hash = FNV1a(key) ^ seed
↓
Unpredictable bucket distribution
↓
DoS attacks prevented ✓
| Feature | Protection | Implementation |
|---|---|---|
| Hash Seeding | DoS attacks | FNV1a(key) ^ seed |
| Secure Wipe | Data leakage | memset(0) before free |
| Overflow Check | Integer overflow | a * b < SIZE_MAX |
| Bounds Check | Buffer overflow | Index validation |
| NULL Check | Null pointer | Pointer validation |
IntVector vec;
// Initialization
nv_init_int(&vec); // Standard init
nv_init_ex_int(&vec, NANODS_FLAG_SECURE); // 🆕 With secure flag
// Modification
nv_push_int(&vec, 42);
nv_pop_int(&vec, &value);
nv_set_int(&vec, index, value);
nv_reserve_int(&vec, 1000);
nv_clear_int(&vec);
// Access
nv_get_int(&vec, index, &value);
size_t size = nv_size_int(&vec);
int empty = nv_empty_int(&vec);
// Functional (v0.1.1+)
nv_map_int(&vec, &result, transform_fn);
nv_filter_int(&vec, &result, predicate_fn);
// 🆕 Iterator (v1.0.0)
NanoIter it = nv_iter_int(&vec);
while (!it.finished) {
int* val = (int*)it.ptr;
nv_iter_next_int(&it);
}
// Cleanup
nv_free_int(&vec); // Standard free
nv_secure_free_int(&vec); // Force secure wipeIntList2 list;
// Initialization
nl2_init_int(&list);
nl2_init_ex_int(&list, NANODS_FLAG_SECURE); // 🆕
// Modification
nl2_push_front_int(&list, 10);
nl2_push_back_int(&list, 20);
nl2_pop_front_int(&list, &val);
nl2_pop_back_int(&list, &val); // 🆕 O(1)!
// Advanced
nl2_insert_after_int(&list, node, value); // 🆕
nl2_remove_node_int(&list, node); // 🆕
// Query
size_t size = nl2_size_int(&list);
int empty = nl2_empty_int(&list);
// 🆕 Iterator
NanoIter it = nl2_iter_int(&list);
// Cleanup
nl2_free_int(&list);IntRing64 ring; // Fixed size: 64 elements
// Initialization
nr_init_int_64(&ring);
nr_init_ex_int_64(&ring, NANODS_FLAG_SECURE); // 🆕
// Write/Read
nr_write_int_64(&ring, 42); // Write (fails if full)
nr_read_int_64(&ring, &val); // Read (FIFO)
nr_peek_int_64(&ring, &val); // Peek without removing
// Query
int full = nr_is_full_int_64(&ring);
int empty = nr_is_empty_int_64(&ring);
size_t size = nr_size_int_64(&ring);
size_t cap = nr_capacity_int_64(&ring);
// Cleanup
nr_clear_int_64(&ring); // Clear (secure if flag set)Pre-defined sizes: 16, 32, 64, 128, 256
NanoMap map;
// Initialization
nm_init(&map); // 🆕 Auto-seeded
nm_init_ex(&map, NANODS_FLAG_SECURE); // 🆕 With secure flag
nm_init_with_capacity(&map, 1000); // Pre-allocate
nm_init_with_capacity_ex(&map, 1000, flags); // 🆕
// Modification
nm_set(&map, "key", &value);
nm_remove(&map, "key");
nm_clear(&map);
// Access
void* val = nm_get(&map, "key");
int exists = nm_has(&map, "key");
// 🆕 Security
printf("Seed: 0x%08X\n", map.seed); // View randomized seed
// Iterator
NanoMapIterator iter;
nm_iter_init(&iter, &map);
const char* key;
void* value;
while (nm_iter_next(&iter, &key, &value) == NANODS_OK) {
// Process key-value pair
}
// Cleanup
nm_free(&map);
nm_secure_free(&map); // Force secure wipevoid* my_malloc(size_t size) {
return pool_alloc(size);
}
void* my_realloc(void* ptr, size_t size) {
return pool_realloc(ptr, size);
}
void my_free(void* ptr) {
pool_free(ptr);
}
int main(void) {
NanoAllocator allocator = {
.malloc_fn = my_malloc,
.realloc_fn = my_realloc,
. free_fn = my_free
};
nanods_set_allocator(&allocator);
// All NanoDS operations now use custom allocator
IntVector vec;
nv_init_int(&vec);
// ...
return 0;
}IntVector vec;
nv_init_int(&vec);
int err = nv_push_int(&vec, 42);
if (err != NANODS_OK) {
switch (err) {
case NANODS_ERR_NOMEM:
fprintf(stderr, "Out of memory\n");
break;
case NANODS_ERR_NULL:
fprintf(stderr, "Null pointer\n");
break;
case NANODS_ERR_OVERFLOW:
fprintf(stderr, "Integer overflow\n");
break;
case NANODS_ERR_FULL: // 🆕 v1.0.0
fprintf(stderr, "Container full\n");
break;
}
}
nv_free_int(&vec);Error codes:
NANODS_OK- SuccessNANODS_ERR_NOMEM- Out of memoryNANODS_ERR_BOUNDS- Index out of boundsNANODS_ERR_EMPTY- Container is emptyNANODS_ERR_OVERFLOW- Integer overflowNANODS_ERR_NOTFOUND- Key not foundNANODS_ERR_NULL- NULL pointerNANODS_ERR_FULL- Container full (ring buffers) 🆕
# Option 1: Add as subdirectory
add_subdirectory(NanoDS)
target_link_libraries(myapp PRIVATE nanods)
# Option 2: Find installed package
find_package(nanods 1.0.0 REQUIRED)
target_link_libraries(myapp PRIVATE nanods:: nanods)
# Option 3: FetchContent
include(FetchContent)
FetchContent_Declare(
nanods
GIT_REPOSITORY https://github.com/Nowazish-Nur-Kayef/NanoDS. git
GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(nanods)
target_link_libraries(myapp PRIVATE nanods)# Check installation
pkg-config --modversion nanods
# Compile
gcc $(pkg-config --cflags nanods) myapp.c -o myapp
# In Makefile
CFLAGS += $(shell pkg-config --cflags nanods)CFLAGS = -std=c11 -Wall -Wextra -I/path/to/nanods
myapp: myapp.c
$(CC) $(CFLAGS) $< -o $@# Basic tests
make test
make run
# Memory leak check
make valgrind
# Hard safety mode
make safe
./nanods_test
# All tests
make clean && make run && make run-benchmarksNanoDS v1.0.0 is tested on every commit:
| Platform | Compilers | Tests |
|---|---|---|
| Ubuntu | GCC 11-12, Clang 14-15 | 12 jobs |
| macOS | Clang (Apple) | 12 jobs |
| Windows | MinGW GCC | 12 jobs |
Total: 36+ test variations
- ✅ Valgrind (zero leaks)
- ✅ Hard safety mode
- ✅ Security validation
- ✅ Performance baseline
- ✅ Documentation check
| Industry | Use Case | NanoDS Solution |
|---|---|---|
| 🎮 Game Dev | Entity systems | Vector + iterators |
| 🔧 Embedded | Sensor buffers | Ring buffers (zero heap) |
| 🛠️ Systems | Driver data | Lists with secure flags |
| 📊 Data Processing | Log parsing | Map with Anti-DoS |
| 🔐 Security | Password managers | Secure flags |
| 🌐 Networking | Connection pools | Lists + custom allocators |
| 🎵 Audio/Video | Real-time buffers | Ring buffers |
| 🤖 Robotics | Command queues | Ring + stacks |
- 📘 API Reference - Complete function documentation
- 📝 DESIGN. md - Architecture deep-dive
- 📊 Big-O Table - Performance characteristics
- 💻 Examples - Real-world usage
- 🧪 Tests - Comprehensive test suite
- 📈 Benchmarks - Performance measurements
- Getting Started
- [Security Features][#-security]
- Performance Benchmarks
- Migration from v0.1.1
All v0.1.1 code works in v1.0.0 without modifications!
// v0.1.1 code
#define NANODS_IMPLEMENTATION
#include "nanods. h"
IntVector vec;
nv_init_int(&vec);
nv_push_int(&vec, 42);
nv_free_int(&vec);
// ✅ Still works in v1.0.0! // NEW: Secure flag
IntVector vec;
nv_init_ex_int(&vec, NANODS_FLAG_SECURE); // Memory auto-wiped
// NEW: Doubly linked list
IntList2 list;
nl2_init_int(&list);
nl2_push_back_int(&list, 10);
// NEW: Ring buffer
IntRing64 ring;
nr_init_int_64(&ring);
nr_write_int_64(&ring, 42);
// NEW: Universal iterator
NanoIter it = nv_iter_int(&vec);
// NEW: Hash seeding (automatic)
nanods_seed_init(0); // Call once at startup- Priority queue (binary heap)
- Binary search tree
- More iterator combinators (zip, fold)
- Concurrent data structures (optional)
- Graph data structures
- String utilities
- SIMD optimizations
Vote on features: GitHub Discussions
Contributions welcome!
- 🐛 Report Bugs: Open an issue
- 💡 Suggest Features: Start a discussion
- 📖 Improve Docs: Submit a PR
- ⭐ Star the Repo: Help others discover NanoDS
| 🔐 | Security Hardened Anti-DoS protection, secure memory wiping |
| ⚡ | Performance Optimized Compiler hints, cache-friendly, zero overhead |
| 🛡️ | Memory Safe Valgrind verified, bounds checked, overflow protected |
| 📦 | Feature Complete 6 data structures, universal iterators, functional ops |
| 🧪 | Battle Tested 36+ CI/CD tests, cross-platform verified |
| 📚 | Well Documented Design docs, API reference, real examples |
- MIT License - See LICENSE
Choose whichever works for your project.
- Inspired by stb libraries by Sean Barrett
- FNV-1a hash algorithm by Fowler, Noll, and Vo
- Security design influenced by Python, Ruby, and Java hash implementations
Need help?
- �� Bug Reports: Open an issue
- 💬 Questions: Start a discussion
- 📖 Documentation: Read DESIGN.md
If NanoDS v1.0.0 helps your project:
⭐ Star the repository
🐦 Share with the C community
💬 Provide feedback
Every star motivates continued development!
wget https://raw.githubusercontent.com/Nowazish-Nur-Kayef/NanoDS/v1.0.0/nanods.hOr clone:
git clone --branch v1.0.0 https://github.com/Nowazish-Nur-Kayef/NanoDS.git
Made with ❤️ for the C community
Production-ready • Memory-safe • Anti-DoS • Zero dependencies
NanoDS v1.0.0 - The Production Standard