Blob Blame History Raw
/*
   Copyright (c) 2015 Red Hat, Inc. <http://www.redhat.com>
   This file is part of GlusterFS.

   This file is licensed to you under your choice of the GNU Lesser
   General Public License, version 3 or any later version (LGPLv3 or
   later), or the GNU General Public License, version 2 (GPLv2), in all
   cases as published by the Free Software Foundation.
*/
#ifndef __GFDB_DATA_STORE_H
#define __GFDB_DATA_STORE_H

#include "glusterfs/glusterfs.h"
#include "glusterfs/xlator.h"
#include "glusterfs/logging.h"
#include "glusterfs/common-utils.h"
#include <time.h>
#include <sys/time.h>

#include "gfdb_data_store_types.h"

/* GFDB Connection Node:
 * ~~~~~~~~~~~~~~~~~~~~
 * Represents the connection to the database while using libgfdb
 * The connection node is not thread safe as far as fini_db is concerned.
 * You can use a single connection node
 * to do multithreaded db operations like insert/delete/find of records.
 * But you need to wait for all the operating threads to complete i.e
 * pthread_join() and then do fini_db() to kill the connection node.
 * gfdb_conn_node_t is an opaque structure.
 * */
typedef struct gfdb_conn_node_t gfdb_conn_node_t;

/*Libgfdb API Function: Used to initialize db connection
 * Arguments:
 *      args         :  Dictionary containing database specific parameters
 *                      eg: For sqlite3, pagesize, cachesize, db name, db path
                        etc
 *      gfdb_db_type :  Type of data base used i.e sqlite or hyperdex etc
 * Returns : if successful return the GFDB Connection Node to the caller or
 *          NULL value in case of failure*/
gfdb_conn_node_t *
init_db(dict_t *arg, gfdb_db_type_t db_type);

typedef gfdb_conn_node_t *(*init_db_t)(dict_t *args,
                                       gfdb_db_type_t gfdb_db_type);

/*Libgfdb API Function: Used to terminate/de-initialize db connection
 *                      (Destructor function for db connection object)
 * Arguments:
 *      _conn_node  :  DB Connection Index of the DB Connection
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
fini_db(gfdb_conn_node_t *);

typedef int (*fini_db_t)(gfdb_conn_node_t *_conn_node);

/*Libgfdb API Function: Used to insert/updated records in the database
 *                      NOTE: In current gfdb_sqlite plugin we use that
 *                      same function to delete the record. Set the
 *                      gfdb_fop_path to GFDB_FOP_UNDEL to delete the
 *                      link of inode from GF_FLINK_TB and
 *                      GFDB_FOP_UNDEL_ALL to delete all the records from
 *                      GF_FLINK_TB and GF_FILE_TB.
 *                      TODO: Should separate this function into the
 *                      delete_record function
 *                      Refer CTR Xlator features/changetimerecorder for usage
 * Arguments:
 *      _conn_node     :  GFDB Connection node
 *      gfdb_db_record :  Record to be inserted/updated
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
insert_record(gfdb_conn_node_t *, gfdb_db_record_t *gfdb_db_record);

/*Libgfdb API Function: Used to delete record from the database
 *                      NOTE: In the current gfdb_sqlite3 plugin
 *                      implementation this function is dummy.
 *                      Use the insert_record function.
 *                      Refer CTR Xlator features/changetimerecorder for usage
 * Arguments:
 *      _conn_node     :  GFDB Connection node
 *      gfdb_db_record :  Record to be deleted
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
delete_record(gfdb_conn_node_t *, gfdb_db_record_t *gfdb_db_record);

/*Libgfdb API Function: Query all the records from the database
 * Arguments:
 *      _conn_node      : GFDB Connection node
 *      query_callback  : Call back function that will be called
 *                        for every record found
 *      _query_cbk_args : Custom argument passed for the call back
 *                        function query_callback
 *      query_limit     : 0 - umlimited,
 *                        any positive value - adds the LIMIT clause
 *                        to the SQL query
 *
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
find_all(gfdb_conn_node_t *, gf_query_callback_t query_callback,
         void *_query_cbk_args, int query_limit);

typedef int (*find_all_t)(gfdb_conn_node_t *,
                          gf_query_callback_t query_callback,
                          void *_query_cbk_args, int query_limit);

/*Libgfdb API Function: Query records/files that have not changed/accessed
 *                      from a time in past to current time
 * Arguments:
 *      _conn_node              : GFDB Connection node
 *      query_callback          : Call back function that will be called
 *                                for every record found
 *      _query_cbk_args         : Custom argument passed for the call back
 *                                function query_callback
 *      for_time                : Time from where the file/s are not
 *                                changed/accessed
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
find_unchanged_for_time(gfdb_conn_node_t *, gf_query_callback_t query_callback,
                        void *_query_cbk_args, gfdb_time_t *for_time);

typedef int (*find_unchanged_for_time_t)(gfdb_conn_node_t *_conn_node,
                                         gf_query_callback_t query_callback,
                                         void *_query_cbk_args,
                                         gfdb_time_t *for_time);

/*Libgfdb API Function: Query records/files that have changed/accessed from a
 *                      time in past to current time
 * Arguments:
 *      _conn_node              : GFDB Connection node
 *      query_callback          : Call back function that will be called
 *                                for every record found
 *      _query_cbk_args         : Custom argument passed for the call back
 *                                function query_callback
 *      for_time                : Time from where the file/s are
 *                                changed/accessed
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
find_recently_changed_files(gfdb_conn_node_t *_conn,
                            gf_query_callback_t query_callback,
                            void *_query_cbk_args, gfdb_time_t *from_time);

typedef int (*find_recently_changed_files_t)(gfdb_conn_node_t *_conn_node,
                                             gf_query_callback_t query_callback,
                                             void *_query_cbk_args,
                                             gfdb_time_t *from_time);

/*Libgfdb API Function: Query records/files that have not changed/accessed
 *                      from a time in past to current time, with
 *                      a desired frequency
 * Arguments:
 *      _conn_node              : GFDB Connection node
 *      query_callback          : Call back function that will be called
 *                                for every record found
 *      _query_cbk_args         : Custom argument passed for the call back
 *                                function query_callback
 *      for_time                : Time from where the file/s are not
 *                                changed/accessed
 *      write_freq_thresold     : Desired Write Frequency lower limit
 *      read_freq_thresold      : Desired Read Frequency lower limit
 *      _clear_counters         : If true, Clears all the frequency counters of
 *                                all files.
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
find_unchanged_for_time_freq(gfdb_conn_node_t *_conn,
                             gf_query_callback_t query_callback,
                             void *_query_cbk_args, gfdb_time_t *for_time,
                             int write_freq_thresold, int read_freq_thresold,
                             gf_boolean_t _clear_counters);

typedef int (*find_unchanged_for_time_freq_t)(
    gfdb_conn_node_t *_conn_node, gf_query_callback_t query_callback,
    void *_query_cbk_args, gfdb_time_t *for_time, int write_freq_thresold,
    int read_freq_thresold, gf_boolean_t _clear_counters);

/*Libgfdb API Function: Query records/files that have changed/accessed from a
 *                      time in past to current time, with
 *                      a desired frequency
 * Arguments:
 *      _conn_node              : GFDB Connection node
 *      query_callback          : Call back function that will be called
 *                                for every record found
 *      _query_cbk_args         : Custom argument passed for the call back
 *                                function query_callback
 *      for_time                : Time from where the file/s are
 *                                changed/accessed
 *      write_freq_thresold     : Desired Write Frequency lower limit
 *      read_freq_thresold      : Desired Read Frequency lower limit
 *      _clear_counters         : If true, Clears all the frequency counters of
 *                                all files.
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
find_recently_changed_files_freq(gfdb_conn_node_t *_conn,
                                 gf_query_callback_t query_callback,
                                 void *_query_cbk_args, gfdb_time_t *from_time,
                                 int write_freq_thresold,
                                 int read_freq_thresold,
                                 gf_boolean_t _clear_counters);

typedef int (*find_recently_changed_files_freq_t)(
    gfdb_conn_node_t *_conn_node, gf_query_callback_t query_callback,
    void *_query_cbk_args, gfdb_time_t *from_time, int write_freq_thresold,
    int read_freq_thresold, gf_boolean_t _clear_counters);

typedef const char *(*get_db_path_key_t)();

/*Libgfdb API Function: Clear the heat for all the files
 *
 * Arguments:
 *      _conn_node              : GFDB Connection node
 *
 * Returns : if successful return 0 or
 *          -ve value in case of failure
 **/
int
clear_files_heat(gfdb_conn_node_t *_conn_node);

typedef int (*clear_files_heat_t)(gfdb_conn_node_t *_conn_node);

/* Libgfdb API Function: Function to extract version of the db
 *  Arguments:
 *      gfdb_conn_node_t *_conn_node        : GFDB Connection node
 *      char **version  : the version is extracted as a string
 *                   and will be stored in this variable.
 *                   The freeing of the memory should be done by the caller.
 * Return:
 *      On success return the length of the version string that is
 *      extracted.
 *      On failure return -1
 * */
int
get_db_version(gfdb_conn_node_t *_conn_node, char **version);

typedef int (*get_db_version_t)(gfdb_conn_node_t *_conn_node, char **version);

/* Libgfdb API Function: Function to extract param from the db
 *  Arguments:
 *      gfdb_conn_node_t *_conn_node        : GFDB Connection node
 *      char *param_key     : param to be extracted
 *      char **param_value  : the value of the param that is
 *                       extracted. This function will allocate memory
 *                       to pragma_value. The caller should free the memory.
 * Return:
 *      On success return the length of the param value that is
 *      extracted.
 *      On failure return -1
 * */
int
get_db_params(gfdb_conn_node_t *_conn_node, char *param_key,
              char **param_value);

typedef int (*get_db_params_t)(gfdb_conn_node_t *db_conn, char *param_key,
                               char **param_value);

/* Libgfdb API Function: Function to set db params
 * Arguments:
 *      gfdb_conn_node_t *_conn_node        : GFDB Connection node
 *      char *param_key     : param to be set
 * char *param_value  : param value
 * Return:
 *      On success return 0
 *      On failure return -1
 * */
int
set_db_params(gfdb_conn_node_t *_conn_node, char *param_key, char *param_value);

typedef int (*set_db_params_t)(gfdb_conn_node_t *db_conn, char *param_key,
                               char *param_value);

/*Libgfdb API Function: Compact the database.
 *
 * Arguments:
 *      _conn_node                      :  GFDB Connection node
 *      _compact_active                 :  Is compaction currently on?
 *      _compact_mode_switched          :  Was the compaction switch flipped?
 * Returns : if successful return 0 or
 *          -ve value in case of failure*/
int
compact_db(gfdb_conn_node_t *_conn_node, gf_boolean_t _compact_active,
           gf_boolean_t _compact_mode_switched);

typedef int (*compact_db_t)(gfdb_conn_node_t *db_conn,
                            gf_boolean_t compact_active,
                            gf_boolean_t compact_mode_switched);

typedef struct gfdb_methods_s {
    init_db_t init_db;
    fini_db_t fini_db;
    find_all_t find_all;
    find_unchanged_for_time_t find_unchanged_for_time;
    find_recently_changed_files_t find_recently_changed_files;
    find_unchanged_for_time_freq_t find_unchanged_for_time_freq;
    find_recently_changed_files_freq_t find_recently_changed_files_freq;
    clear_files_heat_t clear_files_heat;
    get_db_version_t get_db_version;
    get_db_params_t get_db_params;
    set_db_params_t set_db_params;
    /* Do not expose dbpath directly. Expose it via an */
    /* access function: get_db_path_key(). */
    char *dbpath;
    get_db_path_key_t get_db_path_key;

    /* Query Record related functions */
    gfdb_query_record_new_t gfdb_query_record_new;
    gfdb_query_record_free_t gfdb_query_record_free;
    gfdb_add_link_to_query_record_t gfdb_add_link_to_query_record;
    gfdb_write_query_record_t gfdb_write_query_record;
    gfdb_read_query_record_t gfdb_read_query_record;

    /* Link info related functions */
    gfdb_link_info_new_t gfdb_link_info_new;
    gfdb_link_info_free_t gfdb_link_info_free;

    /* Compaction related functions */
    compact_db_t compact_db;
} gfdb_methods_t;

void
get_gfdb_methods(gfdb_methods_t *methods);

typedef void (*get_gfdb_methods_t)(gfdb_methods_t *methods);

#endif