Skip to content

Commit

Permalink
[play] Add code for mmap in Go and C #32
Browse files Browse the repository at this point in the history
- need to deal with raw bytes
- can't put c and golang file in one package, go will try to compile the c file
  • Loading branch information
at15 committed May 9, 2017
1 parent 4f73763 commit 0fc4a0a
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ _testmain.go
.idea
vendor
.vscode
a.out
45 changes: 45 additions & 0 deletions doc/survey/lmdb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# LMDB:

## Ref

- [Howard Chu - LMDB The Databaseology Lectures - CMU Fall 2015](https://youtu.be/tEa5sAh-kVk?t=24m36s)

## Design

- similar to append only B+
- the root noode is always written last
- this really **likes Akumuli**
- but disk space grows without bound
- WAL
- only have two fixed root nodes
- pick the one is newest when cold start
- [ ] because they just need two versions?
- two B+ trees per root node
- one store user data
- one keep track of free space
- single writer concurrent with many readers
- transaction handling
- skipped
- a memory mapped reader table

Dark Underside

- assume uniform record size
- can't use sibling pointers

Page Pointers

- naive code mallocs pointer structs to point to pages and their parents
- LMDB: fixed size stack

Cursor Tracking

- BerkeleyDB sets a tombstone
- SQLite3 invalidates all open cursors
- LMDB updates all open cursors

Turn read ahead off?

- shadow paging?

Multi thread, faster than Memached because no lock?
48 changes: 48 additions & 0 deletions playground/mmap-c/mmapdemo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>
// http://beej.us/guide/bgipc/output/html/multipage/mmap.html

int main(int argc, char *argv[])
{
int fd, offset;
char *data;
struct stat sbuf;

if (argc != 2) {
fprintf(stderr, "usage: mmapdemo offset\n");
exit(1);
}

if ((fd = open("mmapdemo.c", O_RDONLY)) == -1) {
perror("open");
exit(1);
}

if (stat("mmapdemo.c", &sbuf) == -1) {
perror("stat");
exit(1);
}

offset = atoi(argv[1]);
if (offset < 0 || offset > sbuf.st_size-1) {
fprintf(stderr, "mmapdemo: offset must be in the range 0-%d\n", sbuf.st_size-1);
exit(1);
}

data = mmap((caddr_t)0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);

if (data == (caddr_t)(-1)) {
perror("mmap");
exit(1);
}

printf("byte at offset %d is '%c'\n", offset, data[offset]);

return 0;
}
4 changes: 4 additions & 0 deletions playground/mmap/demo.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
abc
123
456
hahaha
43 changes: 43 additions & 0 deletions playground/mmap/mmap_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package mmap

import (
"testing"
"os"
"syscall"
)

// TODO:
// - write
// - write & read struct
// - write in golang, read in C/C++

func TestMmap_Read(t *testing.T) {
// C source files not allowed when not using cgo or SWIG
f, err := os.Open("demo.txt")
if err != nil {
t.Fatal(err)
return
}
stat, err := f.Stat()
size := stat.Size()
// NOTE: from https://github.com/google/codesearch/blob/master/index/mmap_linux.go#L19
// we can't handle single file larger than 4GB, due to the len function does not work with slice longer than 2^32
// TODO: why not use int64(int(size)) == size
if int64(int(size+4095)) != size+4095 {
t.Fatalf("%s: too large for mmap", f.Name())
return
}
n := int(size)
if n == 0 {
t.Fatal("file is empty!")
return
}
// TODO: why codesearch is using (n+4095)&^4095? align to 4KB? I think so
t.Log((n+4095)&^4095)
data, err := syscall.Mmap(int(f.Fd()),0, n, syscall.PROT_READ, syscall.MAP_SHARED)
if err != nil {
t.Fatalf("mmap %s: %v", f.Name(), err)
}
t.Log(len(data))
t.Log(string(data[0:10]))
}

0 comments on commit 0fc4a0a

Please sign in to comment.