I'm trying to store a graph on file using mmap
so i read and write more quickly but i can't read fields struct fields that are created using malloc (and i can't make them an array)
the problem is i can't read back the filed map[i].nodes->vertexKey
from the file
(i think because is because it was created using malloc
)
my code is :
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#define COUNT 10
#define FILESIZE ( COUNT * sizeof(struct vertex))
struct node{
int vertexKey ;
struct node *nextNode;
};
struct vertex {
int vertexKey;
struct node *nodes;
};
int readMmap(){
const char *filepath = "/tmp/mmapped.bin";
int fd = open(filepath, O_RDWR , (mode_t)0600);
if (fd == -1)
{
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
struct stat fileInfo = {0};
if (fstat(fd, &fileInfo) == -1)
{
perror("Error getting the file size");
exit(EXIT_FAILURE);
}
if (fileInfo.st_size == 0)
{
fprintf(stderr, "Error: File is empty, nothing to do\n");
exit(EXIT_FAILURE);
}
printf("File size is %ji\n", (intmax_t)fileInfo.st_size);
struct vertex *map = mmap(0, FILESIZE , PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED)
{
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
for (off_t i = 0; i < COUNT; i++)
{
printf("%d |", map[i].vertexKey );
// i can't read map[i].nodes->vertexKey
printf("%d \n", map[i].nodes->vertexKey );
printf("\n" );
}
// Don't forget to free the mmapped memory
if (munmap(map, fileInfo.st_size) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
// Un-mmaping doesn't close the file, so we still need to do that.
close(fd);
return 0;
}
int writeMmap(){
const char *filepath = "/tmp/mmapped.bin";
int fd = open(filepath, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
if (fd == -1){
perror("Error opening file for writing");
exit(EXIT_FAILURE);
}
if (lseek(fd, FILESIZE-1, SEEK_SET) == -1){
close(fd);
perror("Error calling lseek() to 'stretch' the file");
exit(EXIT_FAILURE);
}
if (write(fd, "", 1) == -1){
close(fd);
perror("Error writing last byte of the file");
exit(EXIT_FAILURE);
}
struct vertex *map = mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
close(fd);
perror("Error mmapping the file");
exit(EXIT_FAILURE);
}
for (size_t i = 0; i < COUNT; i++){
struct vertex ss ;
ss.vertexKey=i;
struct node *n1 = (struct node*)malloc(sizeof(struct node));
n1->nextNode =NULL ;
n1->vertexKey=i*10 ;
ss.nodes = n1 ;
map[i] = ss;
}
// Write it now to disk
if (msync(map, 100, MS_SYNC) == -1)
{
perror("Could not sync the file to disk");
}
// Don't forget to free the mmapped memory
if (munmap(map, 100) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
// Un-mmaping doesn't close the file, so we still need to do that.
close(fd);
return 0;
}
How fast does this really need to be? Using a memory image for your persistent format is a problematic practice -- you need it to be a pretty big win in the larger scheme of things for it to be worthwhile, if it is even possible at all.
If you want a persistent representation of your data, then that representation needs to be self-contained. Pointers per se cannot be supported, but in their place you can use indexes into tables (effectively arrays) of objects. Better would be if indexing were implicit, but that may not be sufficient for you. I apologize for being vague, but I'd need to understand the characteristics of your data much better before I could suggest any specifics.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments