allocate lazy memory to use only required amount
This commit is contained in:
46
plageq.c
46
plageq.c
@@ -1,5 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
||||
@@ -17,8 +17,6 @@ struct node {
|
||||
typedef struct node *iptree;
|
||||
typedef void (*bitsfun)(bits, mask_t, mask_t, mask_t);
|
||||
|
||||
pos_t maxpos = 0;
|
||||
|
||||
void clearb(uint8_t *b) {
|
||||
bzero(b, DEPTHB);
|
||||
}
|
||||
@@ -41,24 +39,37 @@ int getb(uint8_t *b, int n) {
|
||||
}
|
||||
|
||||
iptree iptree_new(pos_t size) {
|
||||
iptree t = malloc(size * sizeof(struct node));
|
||||
if (t == 0) error(1, errno, "iptree_new: malloc failed");
|
||||
pos_t i;
|
||||
for(i = 0; i < size; ++i) {
|
||||
t[i].a[0] = i + 1;
|
||||
t[i].a[1] = 0;
|
||||
clearb(t[i].b);
|
||||
}
|
||||
t[i].a[0] = 0;
|
||||
// use mmap to get pages lazily and zeroed
|
||||
iptree t = mmap(0, size * sizeof(struct node), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if (t == MAP_FAILED) error(1, errno, "iptree_new: mmap failed");
|
||||
// use 2 queues of free nodes
|
||||
t[0].a[0] = 1; // start of continuous range
|
||||
t[0].a[1] = 0; // pointer to a chain of free nodes
|
||||
t[size - 1].a[0] = 1; // end of countinous range marker
|
||||
return t;
|
||||
}
|
||||
|
||||
pos_t iptree_popfree(iptree t) {
|
||||
pos_t f = t[0].a[0];
|
||||
if (f > maxpos) maxpos = f;
|
||||
if (!f) error(1, 0, "iptree_popfree: no free nodes left");
|
||||
t[0].a[0] = t[f].a[0];
|
||||
t[f].a[0] = 0;
|
||||
pos_t f;
|
||||
if (t[0].a[1]) {
|
||||
// try from chain first
|
||||
f = t[0].a[1];
|
||||
t[0].a[1] = t[f].a[0]; // shift pointer to the next node
|
||||
t[f].a[0] = 0; // clear popped element
|
||||
} else if (t[0].a[0]) {
|
||||
// then try if something is left in continuous range
|
||||
f = t[0].a[0]; // start of the range
|
||||
if (t[f].a[0]) {
|
||||
// this is the last element
|
||||
t[0].a[0] = 0;
|
||||
t[f].a[0] = 0; // celar popped element
|
||||
} else {
|
||||
// more elements are there in the range
|
||||
++(t[0].a[0]);
|
||||
}
|
||||
} else {
|
||||
if (!f) error(1, 0, "iptree_popfree: no free nodes left");
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -211,6 +222,7 @@ int main(void) {
|
||||
iptree_traverse(t, ip4, print4);
|
||||
iptree_traverse(t, ip6, print6);
|
||||
|
||||
pos_t maxpos = t[0].a[0] ? t[0].a[0] : SIZE;
|
||||
double mb_used = nodes2mb(maxpos);
|
||||
double mb_all = nodes2mb(SIZE);
|
||||
fprintf(stderr, "max nodes: %.2f%%, %d / %d, %.2fMB / %.2fMB\n", maxpos / (double)SIZE * 100.0, maxpos, SIZE, mb_used, mb_all);
|
||||
|
||||
52
plagmax.c
52
plagmax.c
@@ -1,5 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <errno.h>
|
||||
@@ -11,33 +11,46 @@ struct node { pos_t a[2]; };
|
||||
typedef struct node *iptree;
|
||||
typedef void (*bitsfun)(bits, mask_t);
|
||||
|
||||
pos_t maxpos = 0;
|
||||
|
||||
iptree iptree_new(pos_t size) {
|
||||
iptree t = malloc(size * sizeof(struct node));
|
||||
if (t == 0) error(1, errno, "iptree_new: malloc failed");
|
||||
pos_t i;
|
||||
for(i = 0; i < size; ++i) {
|
||||
t[i].a[0] = i + 1;
|
||||
t[i].a[1] = 0;
|
||||
}
|
||||
t[i].a[0] = 0;
|
||||
// use mmap to get pages lazily and zeroed
|
||||
iptree t = mmap(0, size * sizeof(struct node), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if (t == MAP_FAILED) error(1, errno, "iptree_new: mmap failed");
|
||||
// use 2 queues of free nodes
|
||||
t[0].a[0] = 1; // start of continuous range
|
||||
t[0].a[1] = 0; // pointer to a chain of free nodes
|
||||
t[size - 1].a[0] = 1; // end of countinous range marker
|
||||
return t;
|
||||
}
|
||||
|
||||
pos_t iptree_popfree(iptree t) {
|
||||
pos_t f = t[0].a[0];
|
||||
if (f > maxpos) maxpos = f;
|
||||
if (!f) error(1, 0, "iptree_popfree: no free nodes left");
|
||||
t[0].a[0] = t[f].a[0];
|
||||
t[f].a[0] = 0;
|
||||
pos_t f;
|
||||
if (t[0].a[1]) {
|
||||
// try from chain first
|
||||
f = t[0].a[1];
|
||||
t[0].a[1] = t[f].a[0]; // shift pointer to the next node
|
||||
t[f].a[0] = 0; // clear popped element
|
||||
} else if (t[0].a[0]) {
|
||||
// then try if something is left in continuous range
|
||||
f = t[0].a[0]; // start of the range
|
||||
if (t[f].a[0]) {
|
||||
// this is the last element
|
||||
t[0].a[0] = 0;
|
||||
t[f].a[0] = 0; // celar popped element
|
||||
} else {
|
||||
// more elements are there in the range
|
||||
++(t[0].a[0]);
|
||||
}
|
||||
} else {
|
||||
error(1, 0, "iptree_popfree: no free nodes left");
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
void iptree_pushfree(iptree t, pos_t f) {
|
||||
t[f].a[0] = t[0].a[0];
|
||||
t[f].a[1] = 0;
|
||||
t[0].a[0] = f;
|
||||
// elements are pushed only to the pointer chain
|
||||
t[f].a[0] = t[0].a[1]; // pointer to current head
|
||||
t[f].a[1] = 0; // clear remaining fields
|
||||
t[0].a[1] = f; // redirect the pointer to new head
|
||||
}
|
||||
|
||||
int iptree_is_term(iptree t, pos_t h) {
|
||||
@@ -191,6 +204,7 @@ int main(void) {
|
||||
iptree_traverse(t, ip4, print4);
|
||||
iptree_traverse(t, ip6, print6);
|
||||
|
||||
pos_t maxpos = t[0].a[0] ? t[0].a[0] : SIZE;
|
||||
double mb_used = nodes2mb(maxpos);
|
||||
double mb_all = nodes2mb(SIZE);
|
||||
fprintf(stderr, "max nodes: %.2f%%, %d / %d, %.2fMB / %.2fMB\n", maxpos / (double)SIZE * 100.0, maxpos, SIZE, mb_used, mb_all);
|
||||
|
||||
Reference in New Issue
Block a user