Skip to content

Instantly share code, notes, and snippets.

@tyler
Created September 7, 2009 23:10
Show Gist options
  • Save tyler/182611 to your computer and use it in GitHub Desktop.
Save tyler/182611 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <time.h>
typedef struct _Node {
int key;
int value;
} Node;
typedef struct _BinaryHeap {
Node * root;
char * data;
int next;
int size;
int fd;
} BinaryHeap;
void set_size(BinaryHeap * heap, int size) {
int * data_as_ints = (int *) heap->data;
data_as_ints[1] = size;
}
void set_next(BinaryHeap * heap, int next) {
int * data_as_ints = (int *) heap->data;
data_as_ints[0] = next;
}
BinaryHeap * binary_heap_new(const char * filename) {
int initial_size = 4096;
BinaryHeap * heap = (BinaryHeap *) malloc(sizeof(BinaryHeap));
heap->fd = open(filename, O_RDWR | O_CREAT | O_TRUNC);
lseek(heap->fd, initial_size - 1, SEEK_SET);
write(heap->fd, "", 1);
heap->data = mmap((caddr_t) 0, initial_size, PROT_READ | PROT_WRITE, MAP_SHARED, heap->fd, 0);
heap->root = (Node *) (sizeof(int) * 2 + heap->data);
heap->size = initial_size;
heap->next = 0;
return heap;
}
BinaryHeap * binary_heap_open(const char * filename) {
BinaryHeap * heap = (BinaryHeap *) malloc(sizeof(BinaryHeap));
heap->fd = open(filename, O_RDWR | O_CREAT);
heap->data = mmap((caddr_t) 0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, heap->fd, 0);
heap->root = (Node *) (sizeof(int) * 2 + heap->data);
int * data_as_ints = (int *) heap->data;
heap->next = data_as_ints[0];
heap->size = data_as_ints[1];
return heap;
}
BinaryHeap * binary_heap_close(BinaryHeap * heap) {
set_size(heap, heap->size);
set_next(heap, heap->next);
munmap(heap->root, heap->size);
close(heap->fd);
}
Node * binary_heap_peek(BinaryHeap * heap) {
return heap->root;
}
BinaryHeap * binary_heap_insert(BinaryHeap * heap, int key, int value) {
Node * node = heap->root + heap->next;
node->key = key;
node->value = value;
int current = heap->next;
int parent = (current - 1) / 2;
while(parent >= 0 && heap->root[current].key < heap->root[parent].key) {
Node temp = heap->root[current];
heap->root[current] = heap->root[parent];
heap->root[parent] = temp;
current = parent;
parent = (current - 1) / 2;
}
heap->next++;
return heap;
}
Node binary_heap_delete(BinaryHeap * heap) {
if(heap->next == 0) {
Node blank_node;
blank_node.key = -1;
blank_node.value = -1;
return blank_node;
}
Node root_node = heap->root[0];
heap->next--;
heap->root[0] = heap->root[heap->next];
int current = 0;
int left = 1;
int right = 2;
while(1) {
if(left <= heap->next && heap->root[current].key > heap->root[left].key &&
(right > heap->next || heap->root[left].key < heap->root[right].key)) {
Node temp = heap->root[current];
heap->root[current] = heap->root[left];
heap->root[left] = temp;
current = left;
} else if(right <= heap->next && heap->root[current].key > heap->root[right].key) {
Node temp = heap->root[current];
heap->root[current] = heap->root[right];
heap->root[right] = temp;
current = right;
} else {
break;
}
left = current * 2 + 1;
right = current * 2 + 2;
}
return root_node;
}
int main() {
srand(time(NULL));
BinaryHeap * heap = binary_heap_new("heap.data");
binary_heap_close(heap);
int i;
for(i = 0; i < 10; i++) {
heap = binary_heap_open("heap.data");
int j;
for(j = 0; j < 4; j++) {
binary_heap_insert(heap, ((unsigned)rand() % 10), 1);
}
binary_heap_close(heap);
}
heap = binary_heap_open("heap.data");
Node node;
while((node = binary_heap_delete(heap)).key != -1) {
printf("Dequeue: %d\n", node.key);
}
binary_heap_close(heap);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment