environment.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <unistd.h>
  2. #include "environment.h"
  3. /**
  4. * Static handles.
  5. */
  6. #define DEFAULT_CTX_LABEL "urn:lsup:default"
  7. /** @brief Environment "singleton".
  8. */
  9. LSUP_Env *LSUP_default_env = NULL;
  10. LSUP_Env *
  11. LSUP_env_new (
  12. const char *default_ctx, const char *mdb_path,
  13. const LSUP_NSMap *nsmap)
  14. {
  15. LSUP_Env *env;
  16. CALLOC_GUARD (env, NULL);
  17. // Default store context.
  18. LSUP_Term *default_ctx_uri = LSUP_uri_new (default_ctx);
  19. env->default_ctx = LSUP_buffer_new_from_term (default_ctx_uri);
  20. LSUP_term_free (default_ctx_uri);
  21. log_info ("Set up default context.");
  22. // Set up store if not existing.
  23. if (LSUP_mdbstore_setup (mdb_path, false) != LSUP_OK) return NULL;
  24. env->mdb_store = LSUP_mdbstore_new (mdb_path, env->default_ctx);
  25. if (UNLIKELY (!env->mdb_store)) return NULL;
  26. log_info ("Initialized persistent back end at %s.", mdb_path);
  27. // Get default namespace from store.
  28. RCNL (LSUP_mdbstore_nsm_get (env->mdb_store, &env->nsm));
  29. // Load data types, lang tags from mdb into memory cache.
  30. LSUP_mdbstore_idcache_get (env->mdb_store);
  31. return env;
  32. }
  33. LSUP_rc
  34. LSUP_init (void)
  35. {
  36. LSUP_rc rc = LSUP_NOACTION;
  37. if (LSUP_default_env == NULL) {
  38. #ifdef DEBUG
  39. // In debug mode, always use max logging.
  40. int loglevel = LOG_TRACE;
  41. #else
  42. char *_loglevel = getenv ("LSUP_LOGLEVEL");
  43. int loglevel = (_loglevel == NULL) ? LOG_INFO : atoi (_loglevel);
  44. #endif
  45. log_set_level (loglevel);
  46. // URI validation pattern.
  47. MALLOC_GUARD (LSUP_uri_ptn, LSUP_MEM_ERR);
  48. if (regcomp (LSUP_uri_ptn, LSUP_URI_REGEX_STR, REG_EXTENDED) != 0) {
  49. log_error ("Error compiling regular expression pattern.");
  50. return LSUP_ERROR;
  51. }
  52. // Default literal datatype key.
  53. LSUP_default_dtype_key = XXH32 (
  54. DEFAULT_DTYPE, strlen (DEFAULT_DTYPE) + 1, HASH_SEED);
  55. // Default permanent store path.
  56. char *mdb_path = getenv ("LSUP_MDB_STORE_PATH");
  57. if (!mdb_path) {
  58. mdb_path = DEFAULT_ENV_PATH;
  59. log_warn (
  60. "`LSUP_MDB_STORE_PATH' environment variable is not "
  61. "set. The default location %s will be used as the graph "
  62. "store.", mdb_path
  63. );
  64. }
  65. // Default permanent store.
  66. LSUP_default_env = LSUP_env_new (
  67. DEFAULT_CTX_LABEL, mdb_path, NULL);
  68. // RAM disk store.
  69. if (LSUP_mdbstore_setup (LSUP_MDB_RAMDISK_PATH, true) != LSUP_OK)
  70. log_error ("Error setting up RAM disk store.");
  71. LSUP_default_env->mdb_store_ramdisk = LSUP_mdbstore_new (
  72. LSUP_MDB_RAMDISK_PATH, LSUP_default_env->default_ctx);
  73. if (UNLIKELY (!LSUP_default_env->mdb_store_ramdisk))
  74. log_error ("Error setting up RAM disk store.");
  75. log_info ("Initialized RAM disk back end at %s.", LSUP_MDB_RAMDISK_PATH);
  76. if (!LSUP_default_env) rc = LSUP_DB_ERR;
  77. // Set automatic teardown TODO Is this a good idea?
  78. atexit (LSUP_done);
  79. rc = LSUP_OK;
  80. }
  81. return rc;
  82. }
  83. void
  84. LSUP_env_free (LSUP_Env *env)
  85. {
  86. LSUP_mdbstore_free (env->mdb_store);
  87. LSUP_mdbstore_free (env->mdb_store_ramdisk);
  88. LSUP_buffer_free (env->default_ctx);
  89. LSUP_nsmap_free (env->nsm);
  90. // Free ID cache.
  91. IDCache *entry, *tmp;
  92. HASH_ITER (hh, LSUP_id_cache, entry, tmp) {
  93. HASH_DEL (LSUP_id_cache, entry);
  94. free (entry->data);
  95. free (entry);
  96. }
  97. free (env);
  98. }
  99. void
  100. LSUP_done (void)
  101. {
  102. LSUP_env_free (LSUP_default_env);
  103. regfree (LSUP_uri_ptn);
  104. free (LSUP_uri_ptn);
  105. }