Skip to content

Instantly share code, notes, and snippets.

@mish15
Created March 28, 2014 00:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mish15/9822474 to your computer and use it in GitHub Desktop.
Save mish15/9822474 to your computer and use it in GitHub Desktop.
Using cgo to take memory off heap
package main
/*
#cgo CFLAGS: -O3
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define SJ_REV_BUCKET_SIZE 10000 // The maximum number of terms that the bucket can hold
#define SJ_REV_NUM_BUCKETS 10000
struct sjrev {
uint32_t documentId; // The document the term is in
uint16_t rank; // The rank of the term in the document
uint16_t inMeta; // The bits saving which of the document's meta data the term is in
struct sjrev *next; // The next reverse index record
};
typedef struct sjrev *Rev;
struct sjterm {
struct sjrev *start; // The first reverse index record
};
typedef struct sjterm *TermPtr;
struct sjterm *rev_buckets[SJ_REV_NUM_BUCKETS] = { NULL };
// Dump out the storage (DEBUG)
void Dump() {
struct sjrev *rev;
int bucket, term;
for (bucket = 0; bucket < SJ_REV_NUM_BUCKETS; bucket++) {
if (rev_buckets[bucket] != NULL) {
printf("Bucket[%d]:\n", bucket);
for (term = 0; term < SJ_REV_BUCKET_SIZE; term++) {
if (rev_buckets[bucket][term].start == NULL) continue;
printf(" Term[%d]:\n", (bucket*SJ_REV_BUCKET_SIZE)+term);
rev = rev_buckets[bucket][term].start;
while (rev != NULL) {
printf(" doc=%d, rank=%d, inmeta=%d\n", rev->documentId, rev->rank, rev->inMeta);
rev = rev->next;
}
}
}
}
}
struct sjterm *Term(uint32_t termId) {
uint32_t bucket = termId/SJ_REV_BUCKET_SIZE;
if (bucket < SJ_REV_NUM_BUCKETS) {
if (rev_buckets[bucket] == NULL) {
// Initialise bucket
rev_buckets[bucket] = (struct sjterm *)malloc(SJ_REV_BUCKET_SIZE*sizeof(struct sjterm));
uint32_t tmp = 0;
for (tmp = 0; tmp < SJ_REV_BUCKET_SIZE; tmp++) {
rev_buckets[bucket][tmp].start = NULL;
}
}
return &rev_buckets[bucket][termId-(bucket*SJ_REV_BUCKET_SIZE)];
} else {
printf("Reverse bucket(%d) = <exceeded_size>\n", bucket); // Panic
return NULL;
}
}
// Add a reverse index record to a term
void AddRev(uint32_t termId, uint32_t documentId, uint16_t rank, uint16_t inMeta) {
struct sjterm *term = Term(termId);
if (term == NULL) return; // Couldn't initialise bucket
struct sjrev *rev = (struct sjrev *)malloc(sizeof(struct sjrev));
rev->documentId = documentId;
rev->rank = rank;
rev->inMeta = inMeta;
rev->next = term->start;
term->start = rev;
}
// Remove a reverse index record for a term & document
void RemoveRev(uint32_t termId, uint32_t documentId) {
struct sjterm *term = Term(termId);
if (term == NULL) return; // Couldn't initialise bucket
if (term->start == NULL) return; // No reverse index records
struct sjrev *rev = term->start;
if (rev->documentId == documentId) {
term->start = rev->next;
free(rev);
} else {
while (rev->next != NULL) {
if (rev->next->documentId == documentId) {
struct sjrev *tmp = rev->next;
rev->next = rev->next->next;
free(tmp);
return;
}
rev = rev->next;
}
}
}
*/
import "C"
// Add a reverse index record
func AddCRev(termId uint32, documentId uint32, rank uint16, inMeta uint16) {
C.AddRev(C.uint32_t(termId), C.uint32_t(documentId), C.uint16_t(rank), C.uint16_t(inMeta))
}
// Remove a reverse index record
func RemoveCRev(termId uint32, documentId uint32) {
C.RemoveRev(C.uint32_t(termId), C.uint32_t(documentId));
}
// Return the term as stored in C
func GetCTerm(termId uint32) C.TermPtr {
return C.Term(C.uint32_t(termId))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment