summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cache.c56
-rw-r--r--src/cache.h16
-rw-r--r--src/datagen.c34
-rw-r--r--src/datagen.h8
-rw-r--r--src/defs.h32
-rw-r--r--src/io.c28
-rw-r--r--src/io.h6
-rw-r--r--src/main.c25
-rw-r--r--src/meson.build8
9 files changed, 167 insertions, 46 deletions
diff --git a/src/cache.c b/src/cache.c
new file mode 100644
index 0000000..c88cc78
--- /dev/null
+++ b/src/cache.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
+#include <errno.h>
+#include <stdlib.h>
+#include "defs.h"
+
+int cache_create(struct stream * const restrict in, const struct settings * const restrict s)
+{
+ int ret;
+ void *cache;
+
+ try(!(cache = calloc(in->n, s->stride)), err, ENOMEM);
+
+ in->cache = cache;
+err:
+ return ret;
+}
+
+int cache_populate(struct stream * const restrict in)
+{
+ int ret = 0;
+ ssize_t i;
+
+ for (i = 0; i < in->n; ++i) {
+ try_s((ret = in->get_element(in, i, in->cache + i)), err);
+ }
+
+err:
+ return ret;
+}
+
+int cache_flush(struct stream * const in)
+{
+ int ret;
+ ssize_t i;
+
+ for (i = 0; i < in->n; ++i) {
+ try_s((ret = in->put_element(in, i, in->cache + i)), err);
+ }
+
+err:
+ return ret;
+}
+
+int cache_destroy(struct stream * const in)
+{
+ int ret;
+
+ try(!in->cache, err, EINVAL);
+ free(in->cache);
+ in->cache = NULL;
+err:
+ return ret;
+}
diff --git a/src/cache.h b/src/cache.h
new file mode 100644
index 0000000..0607112
--- /dev/null
+++ b/src/cache.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
+#ifndef ALGOS_CACHE_H_INCLUDED
+#define ALGOS_CACHE_H_INCLUDED
+
+#include <stddef.h>
+#include "defs.h"
+
+int cache_create(struct stream * const restrict in, const struct settings * const restrict s);
+int cache_populate(struct stream * const restrict in);
+int cache_flush(struct stream * const in);
+int cache_destroy(struct stream * const in);
+
+#endif /* ALGOS_CACHE_H_INCLUDED */
diff --git a/src/datagen.c b/src/datagen.c
index 9efe3b3..d4c8bab 100644
--- a/src/datagen.c
+++ b/src/datagen.c
@@ -1,19 +1,20 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
#include <unistd.h>
#include <stddef.h>
#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
#include "datagen.h"
#include "defs.h"
-int gen_get(struct stream *in, size_t idx, struct entry_l *data, int tag)
+int gen_get_array(struct stream * const restrict in, ssize_t idx, struct entry_l * const data)
{
int ret = 0;
(void) idx;
- if (tag) {
- data->prev = 0;
- data->next = 0;
- }
-
in->prev_idx = -1;
ret = read(in->fd, &data->val, sizeof(data->val));
@@ -23,3 +24,24 @@ int gen_get(struct stream *in, size_t idx, struct entry_l *data, int tag)
return ret;
}
+
+int gen_get_list(struct stream * const restrict in, ssize_t idx, struct entry_l * const data)
+{
+ int ret = 0;
+
+ data->prev = idx > 0 ? idx - 1 : labs(idx) - 1;
+ data->next = idx + 1;
+
+ if (!idx) {
+ data->val = 0; /* header lmao */
+ } else {
+ ret = gen_get_array(in, idx, data);
+ }
+
+ return ret;
+}
+
+int gen_put(struct stream * const restrict in, ssize_t idx, const struct entry_l * const data)
+{
+ return ENOSYS;
+}
diff --git a/src/datagen.h b/src/datagen.h
index 7e753ab..63b3461 100644
--- a/src/datagen.h
+++ b/src/datagen.h
@@ -1,8 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
#ifndef ALGOS_DATAGEN_H_INCLUDED
#define ALGOS_DATAGEN_H_INCLUDED
#include "defs.h"
-int gen_get(struct stream *in, size_t idx, struct entry_l *data, int tag);
+int gen_get_array(struct stream * const restrict in, ssize_t idx, struct entry_l * const data);
+int gen_get_list(struct stream * const restrict in, ssize_t idx, struct entry_l * const data);
+int gen_put(struct stream * const restrict in, ssize_t idx, const struct entry_l * const data);
#endif /* ALGOS_DATAGEN_H_INCLUDED */
diff --git a/src/defs.h b/src/defs.h
index 1ad2d72..3b8f1c1 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -1,3 +1,7 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
#ifndef ALGOS_DEFS_H_INCLUDED
#define ALGOS_DEFS_H_INCLUDED
@@ -16,6 +20,9 @@
goto l;\
}} while (0);
+#define get(in, idx, data) (in->cached ? in->get_element_cache(in, idx, data) | in->get_element(in, idx, data))
+#define put(in, idx, data) (in->cached ? in->put_element_cache(in, idx, data) | in->put_element(in, idx, data))
+
/* for array implementation */
struct entry {
uint64_t val;
@@ -24,8 +31,8 @@ struct entry {
/* for linked list implementation */
struct entry_l {
struct entry;
- uint32_t next; /* """pointer""" to the next element. */
- uint32_t prev; /* """pointer""" to the previous element. */
+ int32_t next; /* """pointer""" to the next element. */
+ int32_t prev; /* """pointer""" to the previous element. */
};
enum opmode {
@@ -34,14 +41,28 @@ enum opmode {
mode_generate
};
+enum accessmode {
+ cached,
+ direct
+};
+
+enum dataformat {
+ array,
+ list
+};
+
struct stream {
size_t n;
ssize_t prev_idx;
int fd;
int out;
+ int cached;
char *name;
- int (*get)(struct stream *, size_t, struct entry_l *, int);
- int (*put)(struct stream *, size_t, struct entry_l *, int);
+ struct entry_l *cache;
+ int (*get_element)(struct stream * const restrict, size_t, struct entry_l *);
+ int (*put_element)(struct stream * const restrict, size_t, struct entry_l *);
+ int (*get_element_cache)(struct stream * const restrict, size_t, struct entry_l *);
+ int (*put_element_cache)(struct stream * const restrict, size_t, struct entry_l *);
};
struct settings {
@@ -50,8 +71,9 @@ struct settings {
size_t stride;
char *filein;
char *fileout;
- unsigned int flags;
enum opmode opmode;
+ enum dataformat format;
+ enum accessmode access;
};
#endif /* ALGOS_DEFS_H_INCLUDED */
diff --git a/src/io.c b/src/io.c
index 04f53b1..b18cc00 100644
--- a/src/io.c
+++ b/src/io.c
@@ -1,3 +1,7 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/limits.h>
@@ -11,6 +15,7 @@
#include "io.h"
#include "defs.h"
#include "datagen.h"
+#include "cache.h"
static int stream_open_in(struct stream * const in, const struct settings * const s);
static int stream_open_out(struct stream * const in, const struct settings * const s);
@@ -74,25 +79,6 @@ early_err:
return ret;
}
-int stream_get(struct stream *in, size_t idx, struct entry_l *data, int tag)
-{
- int ret = 0;
-
- ret = in->get(in, idx, data, tag);
-
- return ret;
-}
-
-int stream_put(struct stream *in, size_t idx, struct entry_l *data, int tag)
-{
- int ret = 0;
-
- ret = in->put(in, idx, data, tag);
-
- return ret;
-}
-
-
static int stream_open_out(struct stream * const in, const struct settings * const s)
{
struct stat st;
@@ -133,6 +119,10 @@ static int stream_open_in(struct stream * const in, const struct settings * cons
in->n = st.st_size / s->stride;
in->fd = open(in->name, O_RDONLY | O_NOATIME);
try(in->fd < 0, err, errno); /* TODO: err msg */
+ if (in->cached) {
+ cache_create(in, s);
+ cache_populate(in);
+ }
err:
return ret;
diff --git a/src/io.h b/src/io.h
index d76f2b3..792ebd2 100644
--- a/src/io.h
+++ b/src/io.h
@@ -1,3 +1,7 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
#ifndef ALGOS_IO_H_INCLUDED
#define ALGOS_IO_H_INCLUDED
@@ -5,7 +9,5 @@
int stream_open(struct stream * const in, const struct settings * const s);
int stream_close(struct stream * const in);
-int stream_get(struct stream *in, size_t idx, struct entry_l *data, int tag);
-int stream_put(struct stream *in, size_t idx, struct entry_l *data, int tag);
#endif /* ALGOS_IO_H_INCLUDED */
diff --git a/src/main.c b/src/main.c
index 0d9109f..fabc612 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,3 +1,7 @@
+/* SPDX-License-Identifier: LGPL-2.1-only */
+
+/* Copyright (C) 2020 Gediminas Jakutis */
+
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
@@ -6,9 +10,6 @@
#include "io.h"
#include "defs.h"
-static const unsigned int FLAG_DATA_FORMAT = (1 << 0);
-static const unsigned int FLAG_DATA_ACCESS = (1 << 1);
-
static char randfile[] = "/dev/urandom";
static struct settings settings = {0};
@@ -62,13 +63,13 @@ static int parseargs(int argc, char **argv, struct settings * settings)
} else if (!(strcmp(argv[i], "--generate"))) {
s.opmode = mode_generate;
} else if (!(strcmp(argv[i], "--array"))) {
- s.opmode &= ~FLAG_DATA_FORMAT;
+ s.format = array;
} else if (!(strcmp(argv[i], "--list"))) {
- s.opmode |= FLAG_DATA_FORMAT;
+ s.format = list;
} else if (!(strcmp(argv[i], "--cache"))) {
- s.opmode &= ~FLAG_DATA_ACCESS;
+ s.access = cached;
} else if (!(strcmp(argv[i], "--no-cache"))) {
- s.opmode |= FLAG_DATA_ACCESS;
+ s.access = direct;
} else if (!(strncmp(argv[i], "--position=", 11))) {
if (strlen(argv[i]) > 11) {
s.ss = strtoul(argv[i] + 11, NULL, 10);
@@ -104,13 +105,17 @@ static int parseargs(int argc, char **argv, struct settings * settings)
if (s.opmode == mode_generate) {
- /* we always generate in-memory for speed */
- s.opmode &= ~FLAG_DATA_ACCESS;
+ /* we always generate in-memory for PERFORMANCE */
+ s.access = cached;
+ if (s.format == list) {
+ /* we need to generate the empty header, too */
+ ++s.to;
+ }
} else if (s.opmode == mode_fetch) {
s.to = s.ss + s.to;
}
- s.stride = s.opmode & FLAG_DATA_FORMAT ? sizeof(struct entry_l) : sizeof(struct entry);
+ s.stride = s.format == list ? sizeof(struct entry_l) : sizeof(struct entry);
*settings = s;
diff --git a/src/meson.build b/src/meson.build
index f353e54..f94cce4 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,13 +1,15 @@
source_files = [
- 'main.c',
- 'io.c',
+ 'cache.c',
'datagen.c',
+ 'io.c',
+ 'main.c',
]
header_files = [
- 'io.h',
+ 'cache.h',
'defs.h',
'datagen.h',
+ 'io.h',
]
sources = files(source_files)