Skip to content

Coder-Priyan/VectorDB

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VectorDB

Semantic Search Engine

A vector database implemented from first principles in C++ — three search algorithms, a local embedding pipeline, and a retrieval-augmented generation system, with no external vector database dependency.

C++17 HNSW Ollama REST API MIT License


Table of Contents


Overview

VectorDB is a semantic search engine built from scratch in C++. It implements three nearest-neighbor search algorithms — Brute Force, KD-Tree, and HNSW — behind a single REST API, renders the vector space live in a browser, and runs a complete retrieval-augmented generation (RAG) pipeline against a locally hosted LLM via Ollama.

Nothing in this system wraps an existing vector database. The index, the search algorithms, the embedding pipeline, and the RAG orchestration are all implemented directly in this codebase.


Why This Project Exists

Vector search is the retrieval layer behind nearly every modern semantic search and RAG system, but it's almost always consumed as a hosted API. This project exists to answer, with working code rather than documentation, the questions that usually stay unanswered:

  • What does an HNSW graph actually look like, and why does it outperform simpler structures at scale?
  • At what point does a classical spatial index (KD-Tree) stop being useful as dimensionality increases?
  • What does a RAG pipeline actually do, step by step, when it retrieves context and generates an answer?

Answering these required three algorithms implemented side-by-side on the same data, a way to inspect their internal structure and performance directly, and a real application — RAG — built on top to prove the index is usable, not just theoretically correct.


Feature Highlights

🔍 Three Search Algorithms Brute Force, KD-Tree, and HNSW behind one API, switchable per request
📐 Three Distance Metrics Cosine, Euclidean, Manhattan — selectable independently of algorithm
🕸️ A Real HNSW Implementation Multilayer graph with greedy descent, beam search, and bidirectional linking
📊 Live Vector Space Visualization PCA-projected 2D scatter plot, updated in real time
🧠 Real Embeddings Arbitrary text embedded at 768D via Ollama's nomic-embed-text
🤖 Local RAG Pipeline Retrieval + generation entirely offline via Ollama's llama3.2
Built-In Benchmarking One endpoint runs all three algorithms on the same query for direct comparison

Architecture Overview

graph TD
    UI[Browser UI] -->|HTTP| SRV[C++ Server — cpp-httplib]
    SRV --> VDB[VectorDB]
    SRV --> DDB[DocumentDB]
    SRV --> OC[OllamaClient]

    VDB --> BF[Brute Force]
    VDB --> KD[KD-Tree]
    VDB --> HN[HNSW]

    DDB --> HN2[HNSW — 768D Index]

    OC -->|HTTP| OL[Ollama Runtime]
    OL --> EMB[nomic-embed-text]
    OL --> GEN[llama3.2]
Loading

VectorDB serves the 16-dimensional demo dataset and dispatches to whichever algorithm a query requests. DocumentDB is a separate, HNSW-only index for real 768-dimensional embeddings. OllamaClient is the sole component with any dependency outside the process — a local HTTP call to a running Ollama instance.

A full component breakdown lives in the Technical Requirements Document.


Search Algorithm Comparison

Brute Force KD-Tree HNSW
Type Exact Exact Approximate
Time Complexity O(N·d) O(log N) avg. O(log N) avg.
16D (demo) Correct, slow Correct, fast Correct, fast
768D (real embeddings) Correct, slow Degrades toward brute force Unaffected
Used In Ground-truth baseline 16D comparison only 16D and 768D indexes

The full reasoning behind this table — and why KD-Tree is intentionally excluded from the 768D index — is covered in Core Components below and in the TRD.


Core Components

HNSW (Hierarchical Navigable Small World) — a multilayer graph where each node is randomly assigned a maximum layer; layer 0 holds every node densely connected, higher layers hold exponentially fewer nodes as long-range shortcuts. Search descends greedily from the top layer, then runs a beam search at layer 0. This is the same algorithmic family used by Pinecone, Weaviate, Chroma, and Milvus.

KD-Tree — a binary space-partitioning tree, splitting along one dimension at a time, cycling by depth. Search prunes subtrees using a hypersphere-vs-hyperplane bound. Exact and fast at low dimensions; its pruning collapses at high dimensions (the curse of dimensionality), which is why it is retained for the 16D demo index but never used for the 768D real-embedding index.

Brute Force — a linear O(N·d) scan, used as the correctness baseline every other algorithm is validated against.

Design rationale and data structures for each are documented in Backend Schema.


Embedding Pipeline

Long input text is split into overlapping ~250-word chunks, so retrieval can return a specific relevant passage instead of an entire document. Each chunk is sent to Ollama's nomic-embed-text model and stored as a 768-dimensional vector in DocumentDB's HNSW index.


Local RAG Pipeline

A user's question is embedded the same way as documents, HNSW retrieves the most relevant chunks, and those chunks are assembled into a prompt sent to llama3.2. The generated answer is grounded in retrieved text, and the retrieved chunks are surfaced in the UI rather than hidden — the retrieval step is auditable, not a black box.

Full request-by-request sequence diagrams for this pipeline are in Application Flow.


Screenshots


Search tab — algorithm/metric selection, results, live scatter plot


Ask AI tab — question, streamed answer, expandable retrieved-context chips

Performance

The /benchmark endpoint runs all three algorithms against the same query and returns comparative latency, making the following observations directly reproducible rather than asserted:

  • Brute Force scales linearly with dataset size.
  • KD-Tree is fast at the project's 16D demo scale; this advantage is dimension-dependent and does not hold at 768D.
  • HNSW remains fast at both 16D and 768D — the reason it is the only algorithm used for real embeddings.

Local LLM generation time depends on host hardware; llama3.2 typically takes 10–30 seconds on a laptop CPU, with llama3.2:1b available as a faster fallback.


Tech Stack

Layer Technology
Backend C++17
HTTP Server cpp-httplib (single-header)
Networking Winsock (-lws2_32)
Frontend HTML / CSS / vanilla JavaScript
Visualization Canvas 2D, client-side PCA projection
Embeddings Ollama — nomic-embed-text (768D)
Generation Ollama — llama3.2
Build Toolchain MSYS2 / g++ (UCRT64)

Project Structure

VectorDB/
├── main.cpp        # BruteForce, KDTree, HNSW, VectorDB, DocumentDB, OllamaClient, REST routes
├── httplib.h        # cpp-httplib — single-header HTTP server
├── index.html        # Frontend — scatter plot, search UI, RAG chat UI
└── README.md

Future Roadmap

  • Disk persistence for VectorDB and DocumentDB (currently in-memory only)
  • Expose HNSW tuning parameters (M, ef, ef_construction) via API/UI
  • Support additional local embedding/generation models
  • Cross-platform build instructions (currently Windows/MSYS2 only)

Documentation

Document Purpose
Product Requirements Problem, objectives, scope, success metrics
Technical Requirements Architecture, components, algorithms, data flow
Application Flow Request lifecycle, sequence diagrams
UI/UX Design Brief Design philosophy, layout, user journey
Backend Schema Data structures, relationships, design rationale
Implementation Plan Milestones, development strategy

Installation

Prerequisites: MSYS2 (g++), Git, Ollama

ollama pull nomic-embed-text
ollama pull llama3.2

git clone https://github.com/YOUR_USERNAME/VectorDB.git
cd VectorDB
g++ -std=c++17 -O2 main.cpp -o db -lws2_32

ollama serve
./db

Open http://localhost:8080.

Troubleshooting & full REST API reference
Problem Fix
Ollama: OFFLINE in header Run ollama serve
g++: command not found Add C:\msys64\ucrt64\bin to PATH
Port 8080 in use netstat -ano | findstr 8080taskkill /PID <pid> /F
RAG answers are slow Try ollama pull llama3.2:1b, update genModel in main.cpp

Demo Vector Endpoints: GET /search, POST /insert, DELETE /delete/:id, GET /items, GET /benchmark, GET /hnsw-info, GET /stats

Document & RAG Endpoints: POST /doc/insert, GET /doc/list, DELETE /doc/delete/:id, POST /doc/ask, GET /status

Full parameter details are in the Technical Requirements Document.


License: MIT

About

A Vector Database built from scratch in C++ featuring HNSW, KD-Tree, Brute Force Search, and a local RAG pipeline powered by Ollama.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages