Skip to content

Nowazish-Nur-Kayef/NanoDS

Repository files navigation

⚡ NanoDS v1.0.0

The Production Standard for Memory-Safe Data Structures in C

License:  MIT Language:  C C Standard GitHub release (latest by date) Memory Safe Zero Dependencies Anti-DoS

Single-header • Type-safe • Memory-safe • Anti-DoS • Zero dependencies

FeaturesQuick StartExamplesPerformanceSecurityDocumentation

GitHub stars GitHub forks

🎯 Why NanoDS v1.0.0?

NanoDS v1.0.0 is the production-ready release that brings enterprise-grade security, advanced data structures, and universal APIs to C programming.

❌ Before NanoDS

// 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");

✅ With NanoDS v1.0.0

#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

🆕 What's New in v1.0.0?

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

✨ Features

🔒 Security First

Hash Randomization (NEW)

nanods_seed_init(0);  // Auto-generate seed
NanoMap map;
nm_init(&map);
printf("Seed: 0x%08X\n", map.seed);
// Different every run → DoS resistant

Protects against:

  • Hash-flooding attacks
  • Predictable collisions
  • Denial of service

Secure Memory Wiping (NEW)

IntVector passwords;
nv_init_ex_int(&passwords, 
               NANODS_FLAG_SECURE);
// ...  store passwords ... 
nv_free_int(&passwords);
// Memory automatically zeroed! 

Use cases:

  • Password storage
  • Cryptographic keys
  • Sensitive user data

🚀 Performance

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


📊 Complete Big-O Complexity Table

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)


📦 Data Structures

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

🚀 Quick Start

Installation

Option 1: Direct Download

wget https://raw.githubusercontent.com/Nowazish-Nur-Kayef/NanoDS/main/nanods.h

Option 2: Clone Repository

git clone https://github.com/Nowazish-Nur-Kayef/NanoDS.git
cd NanoDS
make run  # Build and run tests

Option 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)

🎮 Real-World Examples

Example 1: Doubly Linked List (NEW in v1.0.0)

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

Example 2: Ring Buffer for Sensor Data (NEW in v1.0.0)

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

Example 3: Secure Password Storage (NEW in v1.0.0)

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) before free()
  • ✅ No sensitive data in freed memory
  • ✅ Protects against memory dump attacks

Example 4: Universal Iterator (NEW in v1.0.0)

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

Example 5: Hash Map with Anti-DoS (v1.0.0)

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

Example 6: Functional Programming in C

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 

🛡️ Security

Hash Randomization Architecture

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 ✓

Security

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

📚 Complete API Reference

Vector Operations

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 wipe

List2 Operations (NEW in v1.0.0)

IntList2 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);

Ring Buffer Operations (NEW in v1.0.0)

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


Map Operations (Updated in v1.0.0)

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 wipe

🔧 Advanced Features

Custom Allocators

void* 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;
}

Error Handling

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 - Success
  • NANODS_ERR_NOMEM - Out of memory
  • NANODS_ERR_BOUNDS - Index out of bounds
  • NANODS_ERR_EMPTY - Container is empty
  • NANODS_ERR_OVERFLOW - Integer overflow
  • NANODS_ERR_NOTFOUND - Key not found
  • NANODS_ERR_NULL - NULL pointer
  • NANODS_ERR_FULL - Container full (ring buffers) 🆕

🏗️ Build System Integration

CMake

# 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)

pkg-config

# Check installation
pkg-config --modversion nanods

# Compile
gcc $(pkg-config --cflags nanods) myapp.c -o myapp

# In Makefile
CFLAGS += $(shell pkg-config --cflags nanods)

Makefile

CFLAGS = -std=c11 -Wall -Wextra -I/path/to/nanods

myapp: myapp.c
	$(CC) $(CFLAGS) $< -o $@

🧪 Testing

Run Tests

# 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-benchmarks

CI/CD

NanoDS 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

🎯 Use Cases

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

📖 Documentation

Resources

Quick Links


🔄 Migration from v0.1.1

✅ Zero Breaking Changes

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 Features (Optional)

// 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

🗺️ Roadmap

v1.1.0 (Planned)

  • Priority queue (binary heap)
  • Binary search tree
  • More iterator combinators (zip, fold)
  • Concurrent data structures (optional)

v1.2.0 (Future)

  • Graph data structures
  • String utilities
  • SIMD optimizations

Vote on features: GitHub Discussions


🤝 Contributing

Contributions welcome!


📊 Project Stats

GitHub contributors GitHub commit activity GitHub last commit Lines of code


🏆 Why v1.0.0 is Production-Ready

🔐 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

📜 License

Choose whichever works for your project.


🙏 Acknowledgments

  • 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

📞 Support

GitHub Issues GitHub Discussions

Need help?


⭐ Show Your Support

If NanoDS v1.0.0 helps your project:

Star the repository
🐦 Share with the C community
💬 Provide feedback

Every star motivates continued development!


📥 Get Started Now

wget https://raw.githubusercontent.com/Nowazish-Nur-Kayef/NanoDS/v1.0.0/nanods.h

Or 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