Created
March 28, 2014 00:36
-
-
Save mish15/9822474 to your computer and use it in GitHub Desktop.
Using cgo to take memory off heap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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