Files
qse/qse/include/qse/cmn/lda.h

424 lines
11 KiB
C

/*
* $Id: lda.h 556 2011-08-31 15:43:46Z hyunghwan.chung $
*
Copyright 2006-2011 Chung, Hyung-Hwan.
This file is part of QSE.
QSE is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
QSE 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with QSE. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _QSE_CMN_LDA_H_
#define _QSE_CMN_LDA_H_
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* This file provides a linear dynamic array. It grows dynamically as items
* are added.
*/
enum qse_lda_walk_t
{
QSE_LDA_WALK_STOP = 0,
QSE_LDA_WALK_FORWARD = 1,
QSE_LDA_WALK_BACKWARD = 2
};
typedef struct qse_lda_t qse_lda_t;
typedef struct qse_lda_slot_t qse_lda_slot_t;
typedef enum qse_lda_walk_t qse_lda_walk_t;
#define QSE_LDA_COPIER_SIMPLE ((qse_lda_copier_t)1)
#define QSE_LDA_COPIER_INLINE ((qse_lda_copier_t)2)
#define QSE_LDA_NIL ((qse_size_t)-1)
#define QSE_LDA_SIZE(lda) (*(const qse_size_t*)&(lda)->size)
#define QSE_LDA_CAPA(lda) (*(const qse_size_t*)&(lda)->capa)
#define QSE_LDA_SLOT(lda,index) ((lda)->slot[index])
#define QSE_LDA_DPTL(lda,index) ((const qse_xptl_t*)&(lda)->slot[index]->val)
#define QSE_LDA_DPTR(lda,index) ((lda)->slot[index]->val.ptr)
#define QSE_LDA_DLEN(lda,index) ((lda)->slot[index]->val.len)
/**
* The qse_lda_copier_t type defines a callback function for slot construction.
* A slot is contructed when a user adds data to a list. The user can
* define how the data to add can be maintained in the list. A singly
* linked list not specified with any copiers stores the data pointer and
* the data length into a slot. A special copier QSE_LDA_COPIER_INLINE copies
* the contents of the data a user provided into the slot. You can use the
* qse_lda_setcopier() function to change the copier.
*
* A copier should return the pointer to the copied data. If it fails to copy
* data, it may return QSE_NULL. You need to set a proper freeer to free up
* memory allocated for copy.
*/
typedef void* (*qse_lda_copier_t) (
qse_lda_t* lda /**< array */,
void* dptr /**< pointer to data to copy */,
qse_size_t dlen /**< length of data to copy */
);
/**
* The qse_lda_freeer_t type defines a slot destruction callback.
*/
typedef void (*qse_lda_freeer_t) (
qse_lda_t* lda /**< array */,
void* dptr /**< pointer to data to free */,
qse_size_t dlen /**< length of data to free */
);
/**
* The qse_lda_comper_t type defines a key comparator that is called when
* the list needs to compare data. A linear dynamic array is created with a
* default comparator that performs bitwise comparison.
*
* The comparator should return 0 if the data are the same and a non-zero
* integer otherwise.
*
*/
typedef int (*qse_lda_comper_t) (
qse_lda_t* lda /* array */,
const void* dptr1 /* data pointer */,
qse_size_t dlen1 /* data length */,
const void* dptr2 /* data pointer */,
qse_size_t dlen2 /* data length */
);
/**
* The qse_lda_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their beginning
* pointers and their lengths are equal.
*/
typedef void (*qse_lda_keeper_t) (
qse_lda_t* lda /**< array */,
void* vptr /**< pointer to a value */,
qse_size_t vlen /**< length of a value */
);
/**
* The qse_lda_sizer_t type defines an array size claculator that is called
* when the array needs to be resized.
*/
typedef qse_size_t (*qse_lda_sizer_t) (
qse_lda_t* lda, /**< array */
qse_size_t hint /**< sizing hint */
);
typedef qse_lda_walk_t (*qse_lda_walker_t) (
qse_lda_t* lda /* array */,
qse_size_t index /* index to the visited slot */,
void* ctx /* user-defined context */
);
/**
* The qse_lda_t type defines a linear dynamic array.
*/
struct qse_lda_t
{
QSE_DEFINE_COMMON_FIELDS (lda)
qse_lda_copier_t copier; /* data copier */
qse_lda_freeer_t freeer; /* data freeer */
qse_lda_comper_t comper; /* data comparator */
qse_lda_keeper_t keeper; /* data keeper */
qse_lda_sizer_t sizer; /* size calculator */
qse_byte_t scale; /* scale factor */
qse_size_t size; /* number of items */
qse_size_t capa; /* capacity */
qse_lda_slot_t** slot;
};
/**
* The qse_lda_slot_t type defines a linear dynamic array slot
*/
struct qse_lda_slot_t
{
qse_xptl_t val;
};
#ifdef __cplusplus
extern "C" {
#endif
QSE_DEFINE_COMMON_FUNCTIONS (lda)
/**
* The qse_lda_open() function creates a linear dynamic array.
*/
qse_lda_t* qse_lda_open (
qse_mmgr_t* mmgr, /**< memory manager */
qse_size_t ext, /**< extension size in bytes */
qse_size_t capa /**< initial array capacity */
);
/**
* The qse_lda_close() function destroys a linear dynamic array.
*/
void qse_lda_close (
qse_lda_t* lda /**< array */
);
/**
* The qse_lda_init() function initializes a linear dynamic array.
*/
int qse_lda_init (
qse_lda_t* lda,
qse_mmgr_t* mmgr,
qse_size_t capa
);
/**
* The qse_lda_fini() function finalizes a linear dynamic array.
*/
void qse_lda_fini (
qse_lda_t* lda /**< array */
);
/**
* The qse_lda_getscale() function returns the scale factor
*/
int qse_lda_getscale (
qse_lda_t* lda /**< array */
);
/**
* The qse_lda_setscale() function sets the scale factor of the length
* of a key and a value. A scale factor determines the actual length of
* a key and a value in bytes. A lda is created with a scale factor of 1.
* The scale factor should be larger than 0 and less than 256.
* It is a bad idea to change the scale factor when @a lda is not empty.
*/
void qse_lda_setscale (
qse_lda_t* lda /**< array */,
int scale /**< scale factor */
);
qse_lda_copier_t qse_lda_getcopier (
qse_lda_t* lda /* array */
);
/**
* The qse_lda_setcopier() specifies how to clone an element. The special
* copier #QSE_LDA_COPIER_INLINE copies the data inline to the internal slot.
* No freeer is invoked when the slot is freeed. You may set the copier to
* #QSE_LDA_COPIER_SIMPLE to perform no special operation when the data
* pointer is stored.
*/
void qse_lda_setcopier (
qse_lda_t* lda /** lda */,
qse_lda_copier_t copier /** element copier */
);
/**
* The qse_lda_getfreeer() function returns a custom element destroyer.
*/
qse_lda_freeer_t qse_lda_getfreeer (
qse_lda_t* lda /**< lda */
);
/**
* The qse_lda_setfreeer() function specifies how to destroy an element.
* The @a freeer is called when a slot containing the element is destroyed.
*/
void qse_lda_setfreeer (
qse_lda_t* lda /**< lda */,
qse_lda_freeer_t freeer /**< element freeer */
);
qse_lda_comper_t qse_lda_getcomper (
qse_lda_t* lda /**< lda */
);
/**
* The qse_lda_setcomper() function specifies how to compare two elements
* for equality test. The comparator @a comper must return 0 if two elements
* compared are equal, or a non-zero number otherwise.
*/
void qse_lda_setcomper (
qse_lda_t* lda /**< lda */,
qse_lda_comper_t comper /**< comparator */
);
qse_lda_keeper_t qse_lda_getkeeper (
qse_lda_t* lda
);
void qse_lda_setkeeper (
qse_lda_t* lda,
qse_lda_keeper_t keeper
);
qse_lda_sizer_t qse_lda_getsizer (
qse_lda_t* lda
);
void qse_lda_setsizer (
qse_lda_t* lda,
qse_lda_sizer_t sizer
);
qse_size_t qse_lda_getsize (
qse_lda_t* lda
);
qse_size_t qse_lda_getcapa (
qse_lda_t* lda
);
qse_lda_t* qse_lda_setcapa (
qse_lda_t* lda,
qse_size_t capa
);
qse_size_t qse_lda_search (
qse_lda_t* lda,
qse_size_t pos,
const void* dptr,
qse_size_t dlen
);
qse_size_t qse_lda_rsearch (
qse_lda_t* lda,
qse_size_t pos,
const void* dptr,
qse_size_t dlen
);
qse_size_t qse_lda_upsert (
qse_lda_t* lda,
qse_size_t index,
void* dptr,
qse_size_t dlen
);
qse_size_t qse_lda_insert (
qse_lda_t* lda,
qse_size_t index,
void* dptr,
qse_size_t dlen
);
qse_size_t qse_lda_update (
qse_lda_t* lda,
qse_size_t pos,
void* dptr,
qse_size_t dlen
);
/**
* The qse_lda_delete() function deletes the as many data as the count
* from the index. It returns the number of data deleted.
*/
qse_size_t qse_lda_delete (
qse_lda_t* lda,
qse_size_t index,
qse_size_t count
);
/**
* The qse_lda_uplete() function deletes data slot without compaction.
* It returns the number of data affected.
*/
qse_size_t qse_lda_uplete (
qse_lda_t* lda,
qse_size_t index,
qse_size_t count
);
void qse_lda_clear (
qse_lda_t* lda
);
/**
* The qse_lda_walk() function calls the @a walker function for each
* element in the array beginning from the first. The @a walker function
* should return one of #QSE_LDA_WALK_FORWARD, #QSE_LDA_WALK_BACKWARD,
* #QSE_LDA_WALK_STOP.
* @return number of calls to the @a walker fucntion made
*/
qse_size_t qse_lda_walk (
qse_lda_t* lda,
qse_lda_walker_t walker,
void* ctx
);
/**
* The qse_lda_rwalk() function calls the @a walker function for each
* element in the array beginning from the last. The @a walker function
* should return one of #QSE_LDA_WALK_FORWARD, #QSE_LDA_WALK_BACKWARD,
* #QSE_LDA_WALK_STOP.
* @return number of calls to the @a walker fucntion made
*/
qse_size_t qse_lda_rwalk (
qse_lda_t* lda,
qse_lda_walker_t walker,
void* ctx
);
/**
* The qse_lda_pushstack() function appends data to the array. It is a utility
* function to allow stack-like operations over an array. To do so, you should
* not play with other non-stack related functions.
*/
qse_size_t qse_lda_pushstack (
qse_lda_t* lda,
void* dptr,
qse_size_t dlen
);
/**
* The qse_lda_popstack() function deletes the last array data. It is a utility
* function to allow stack-like operations over an array. To do so, you should
* not play with other non-stack related functions.
* @note You must not call this function if @a lda is empty.
*/
void qse_lda_popstack (
qse_lda_t* lda
);
/**
* The qse_lda_pushheap() function inserts data to an array while keeping the
* largest data at position 0. It is a utiltiy funtion to implement a binary
* max-heap over an array. Inverse the comparator to implement a min-heap.
* @return number of array elements
* @note You must not mess up the array with other non-heap related functions
* to keep the heap property.
*/
qse_size_t qse_lda_pushheap (
qse_lda_t* lda,
void* dptr,
qse_size_t dlen
);
/**
* The qse_lda_popheap() function deletes data at position 0 while keeping
* the largest data at positon 0. It is a utiltiy funtion to implement a binary
* max-heap over an array.
* @note You must not mess up the array with other non-heap related functions
* to keep the heap property.
*/
void qse_lda_popheap (
qse_lda_t* lda
);
#ifdef __cplusplus
}
#endif
#endif