pxd: initial work
[pspp] / src / libpspp / pxd.h
diff --git a/src/libpspp/pxd.h b/src/libpspp/pxd.h
new file mode 100644 (file)
index 0000000..22b34c4
--- /dev/null
@@ -0,0 +1,254 @@
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 2010, 2012 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef LIBPSPP_PXD_H
+#define LIBPSPP_PXD_H 1
+
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "data/case.h"
+#include "libpspp/hmap.h"
+
+struct pxd;
+struct pxd_object;
+struct pxd_id;
+union value;
+\f
+/* Databases. */
+
+struct pxd *pxd_open (const char *name, bool create);
+void pxd_close (struct pxd *);
+
+struct pxd_object *pxd_fetch (const struct pxd *, const struct pxd_id *);
+void pxd_store (struct pxd *, const struct pxd_object *);
+
+void pxd_get_root (const struct pxd *, struct pxd_id *);
+bool pxd_swap_root (struct pxd *, const struct pxd_id *old_root,
+                    struct pxd_object *new_root);
+\f
+/* Object IDs. */
+
+struct pxd_id
+  {
+    uint32_t opaque[5];
+  };
+
+#define PXD_ID_FMT "%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32
+#define PXD_ID_ARGS(ID)                         \
+        (ID)->opaque[0],                        \
+        (ID)->opaque[1],                        \
+        (ID)->opaque[2],                        \
+        (ID)->opaque[3],                        \
+        (ID)->opaque[4]
+#define PXD_ID_SCAN_ARGS(ID)                    \
+        &(ID)->opaque[0],                       \
+        &(ID)->opaque[1],                       \
+        &(ID)->opaque[2],                       \
+        &(ID)->opaque[3],                       \
+        &(ID)->opaque[4]
+
+static inline bool
+pxd_id_equals (const struct pxd_id *a, const struct pxd_id *b)
+{
+  return (a->opaque[0] == b->opaque[0]
+          && a->opaque[1] == b->opaque[1]
+          && a->opaque[2] == b->opaque[2]
+          && a->opaque[3] == b->opaque[3]
+          && a->opaque[4] == b->opaque[4]);
+}
+
+static inline uint32_t
+pxd_id_hash (const struct pxd_id *id)
+{
+  return id->opaque[0];
+}
+\f
+/* Objects. */
+
+struct pxd_object
+  {
+    struct hmap_node hmap_node;
+    unsigned int n_refs;
+    struct pxd_id id;
+    unsigned int n_links;
+    unsigned int size;
+    struct pxd_id *links;
+    uint8_t *data;
+  };
+
+struct pxd_object *pxd_object_create (const struct pxd_id[], size_t,
+                                      const void *, size_t);
+
+struct pxd_object *pxd_object_ref (const struct pxd_object *);
+void pxd_object_unref (struct pxd_object *);
+
+static inline const struct pxd_id *
+pxd_object_id (const struct pxd_object *obj)
+{
+  return &obj->id;
+}
+
+static inline unsigned int
+pxd_object_get_n_links (const struct pxd_object *obj)
+{
+  return obj->n_links;
+}
+
+static inline const struct pxd_id *
+pxd_object_get_link_id (const struct pxd_object *obj, unsigned int idx)
+{
+  return &obj->links[idx];
+}
+
+static inline struct pxd_object *
+pxd_object_get_link (const struct pxd_object *obj, unsigned int idx,
+                     const struct pxd *pxd)
+{
+  return pxd_fetch (pxd, pxd_object_get_link_id (obj, idx));
+}
+
+static inline unsigned int
+pxd_object_size (const struct pxd_object *obj)
+{
+  return obj->size;
+}
+
+static inline const uint8_t *
+pxd_object_data (const struct pxd_object *obj)
+{
+  return obj->data;
+}
+
+void *pxd_object_raw_data__ (const struct pxd_object *);
+size_t pxd_object_raw_size__ (const struct pxd_object *);
+\f
+/* Object builder. */
+
+struct pxd_builder
+  {
+    struct pxd *pxd;
+
+    struct pxd_id *links;
+    unsigned int n_links, links_allocated;
+
+    uint8_t *data;
+    unsigned int size, data_allocated;
+  };
+
+void pxd_builder_init (struct pxd_builder *, struct pxd *);
+void pxd_builder_destroy (struct pxd_builder *);
+
+struct pxd_object *pxd_builder_commit (struct pxd_builder *);
+
+void *pxd_builder_put_uninit (struct pxd_builder *, size_t);
+void pxd_builder_put (struct pxd_builder *, const void *, size_t);
+void pxd_builder_put_value (struct pxd_builder *,
+                            const union value *, int width);
+void pxd_builder_put_string (struct pxd_builder *, const char *);
+void pxd_builder_put_interned_string (struct pxd_builder *, const char *);
+void pxd_builder_put_bool (struct pxd_builder *, bool);
+void pxd_builder_put_u8 (struct pxd_builder *, unsigned char);
+void pxd_builder_put_u16 (struct pxd_builder *, unsigned short int);
+void pxd_builder_put_u32 (struct pxd_builder *, unsigned int);
+void pxd_builder_put_u64 (struct pxd_builder *, unsigned long long int);
+void pxd_builder_put_s8 (struct pxd_builder *, signed char);
+void pxd_builder_put_s16 (struct pxd_builder *, short int);
+void pxd_builder_put_s32 (struct pxd_builder *, int);
+void pxd_builder_put_s64 (struct pxd_builder *, long long int);
+void pxd_builder_put_size_t (struct pxd_builder *, size_t);
+void pxd_builder_put_casenumber (struct pxd_builder *, casenumber);
+void pxd_builder_put_double (struct pxd_builder *, double);
+
+void pxd_builder_put_link (struct pxd_builder *, struct pxd_object *);
+\f
+/* Object parser. */
+
+struct pxd_parser
+  {
+    struct pxd_object *obj;
+    const struct pxd *pxd;
+    unsigned int offset;
+    unsigned int link;
+  };
+
+void pxd_parser_init (struct pxd_parser *,
+                      struct pxd_object *, const struct pxd *);
+void pxd_parser_destroy (struct pxd_parser *);
+
+const void *pxd_parser_get (struct pxd_parser *, size_t);
+void pxd_parser_get_copy (struct pxd_parser *, void *, size_t);
+void pxd_parser_get_value (struct pxd_parser *, union value *, int width);
+char *pxd_parser_get_string (struct pxd_parser *);
+const char *pxd_parser_get_interned_string (struct pxd_parser *);
+bool pxd_parser_get_bool (struct pxd_parser *);
+unsigned char pxd_parser_get_u8 (struct pxd_parser *);
+unsigned short int pxd_parser_get_u16 (struct pxd_parser *);
+unsigned int pxd_parser_get_u32 (struct pxd_parser *);
+unsigned long long int pxd_parser_get_u64 (struct pxd_parser *);
+signed char pxd_parser_get_s8 (struct pxd_parser *);
+short int pxd_parser_get_s16 (struct pxd_parser *);
+int pxd_parser_get_s32 (struct pxd_parser *);
+long long int pxd_parser_get_s64 (struct pxd_parser *);
+size_t pxd_parser_get_size_t (struct pxd_parser *);
+casenumber pxd_parser_get_casenumber (struct pxd_parser *);
+double pxd_parser_get_double (struct pxd_parser *);
+struct pxd_object *pxd_parser_get_link (struct pxd_parser *);
+\f
+/* Array builder. */
+
+#define PXD_ARRAY_LEVELS 10
+#define PXD_ARRAY_BITS 5
+
+struct pxd_array_builder
+  {
+    struct pxd_builder b;
+  };
+
+void pxd_array_builder_init (struct pxd_array_builder *, struct pxd *);
+void pxd_array_builder_destroy (struct pxd_array_builder *);
+
+struct pxd_object *pxd_array_builder_commit (struct pxd_array_builder *);
+
+void pxd_array_builder_add (struct pxd_array_builder *, struct pxd_object *);
+\f
+/* Array reader. */
+
+struct pxd_array
+  {
+    const struct pxd *pxd;
+    struct pxd_object *obj;
+  };
+
+void pxd_array_init (struct pxd_array *, struct pxd_object *,
+                     const struct pxd *);
+void pxd_array_destroy (struct pxd_array *);
+
+static inline unsigned long long int
+pxd_array_size (const struct pxd_array *array)
+{
+  return array->obj->n_links;
+}
+
+static inline struct pxd_object *
+pxd_array_get (const struct pxd_array *array, unsigned long long int index)
+{
+  return pxd_object_get_link (array->obj, index, array->pxd);
+}
+
+#endif /* libpspp/pxd.h */