⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 darray.c

📁 This is an implementation of double-array structure for representing trie, as proposed by Junichi A
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * darray.c - Double-array trie structure * Created: 2006-08-13 * Author:  Theppitak Karoonboonyanan <thep@linux.thai.net> */#include <string.h>#include <stdlib.h>#include <stdio.h>#include "darray.h"#include "fileutils.h"/*----------------------------------* *    INTERNAL TYPES DECLARATIONS   * *----------------------------------*/typedef struct _Symbols Symbols;struct _Symbols {    short       num_symbols;    TrieChar    symbols[256];};static Symbols *    symbols_new ();static void         symbols_free (Symbols *syms);static void         symbols_add (Symbols *syms, TrieChar c);#define symbols_num(s)          ((s)->num_symbols)#define symbols_get(s,i)        ((s)->symbols[i])#define symbols_add_fast(s,c)   ((s)->symbols[(s)->num_symbols++] = c)/*-----------------------------------* *    PRIVATE METHODS DECLARATIONS   * *-----------------------------------*/#define da_get_free_list(d)      (1)static Bool         da_check_free_cell (DArray         *d,                                        TrieIndex       s);static Bool         da_has_children    (DArray         *d,                                        TrieIndex       s);static Symbols *    da_output_symbols  (DArray         *d,                                        TrieIndex       s);static TrieChar *   da_get_state_key   (DArray         *d,                                        TrieIndex       state);static TrieIndex    da_find_free_base  (DArray         *d,                                        const Symbols  *symbols);static Bool         da_fit_symbols     (DArray         *d,                                        TrieIndex       base,                                        const Symbols  *symbols);static void         da_relocate_base   (DArray         *d,                                        TrieIndex       s,                                        TrieIndex       new_base);static void         da_extend_pool     (DArray         *d,                                        TrieIndex       to_index);static void         da_alloc_cell      (DArray         *d,                                        TrieIndex       cell);static void         da_free_cell       (DArray         *d,                                        TrieIndex       cell);static Bool         da_enumerate_recursive (DArray     *d,                                            TrieIndex   state,                                            DAEnumFunc  enum_func,                                            void       *user_data);/* ==================== BEGIN IMPLEMENTATION PART ====================  *//*------------------------------------* *   INTERNAL TYPES IMPLEMENTATIONS   * *------------------------------------*/static Symbols *symbols_new (){    Symbols *syms;    syms = (Symbols *) malloc (sizeof (Symbols));    if (!syms)        return NULL;    syms->num_symbols = 0;    return syms;}static voidsymbols_free (Symbols *syms){    free (syms);}static voidsymbols_add (Symbols *syms, TrieChar c){    short lower, upper;    lower = 0;    upper = syms->num_symbols;    while (lower < upper) {        short middle;        middle = (lower + upper)/2;        if (c > syms->symbols[middle])            lower = middle + 1;        else if (c < syms->symbols[middle])            upper = middle;        else            return;    }    if (lower < syms->num_symbols) {        memmove (syms->symbols + lower + 1, syms->symbols + lower,                 syms->num_symbols - lower);    }    syms->symbols[lower] = c;    syms->num_symbols++;}/*------------------------------* *    PRIVATE DATA DEFINITONS   * *------------------------------*/typedef struct {    TrieIndex   base;    TrieIndex   check;} DACell;struct _DArray {    TrieIndex   num_cells;    DACell     *cells;    FILE       *file;    Bool        is_dirty;};/*-----------------------------* *    METHODS IMPLEMENTAIONS   * *-----------------------------*/#define DA_SIGNATURE 0xDAFDDArray *da_open (const char *path, const char *name, TrieIOMode mode){    DArray     *d;    TrieIndex   i;    d = (DArray *) malloc (sizeof (DArray));    d->file = file_open (path, name, ".br", mode);    if (!d->file)        goto exit1;    /* init cells data */    d->num_cells = file_length (d->file) / 4;    if (0 == d->num_cells) {        d->num_cells = 3;        d->cells     = (DACell *) malloc (d->num_cells * sizeof (DACell));        if (!d->cells)            goto exit2;        d->cells[0].base = DA_SIGNATURE;        d->cells[0].check = 1;        d->cells[1].base = -1;        d->cells[1].check = -1;        d->cells[2].base = 3;        d->cells[2].check = 0;        d->is_dirty = TRUE;    } else {        d->cells     = (DACell *) malloc (d->num_cells * sizeof (DACell));        if (!d->cells)            goto exit2;        file_read_int16 (d->file, &d->cells[0].base);        file_read_int16 (d->file, &d->cells[0].check);        if (DA_SIGNATURE != (uint16) d->cells[0].base)            goto exit3;        for (i = 1; i < d->num_cells; i++) {            file_read_int16 (d->file, &d->cells[i].base);            file_read_int16 (d->file, &d->cells[i].check);        }        d->is_dirty  = FALSE;    }    return d;exit3:    free (d->cells);exit2:    fclose (d->file);exit1:    free (d);    return NULL;}intda_close (DArray *d){    int ret;    if (0 != (ret = da_save (d)))        return ret;    if (0 != (ret = fclose (d->file)))        return ret;    free (d->cells);    free (d);    return 0;}intda_save (DArray *d){    TrieIndex   i;    if (!d->is_dirty)        return 0;    rewind (d->file);    for (i = 0; i < d->num_cells; i++) {        if (!file_write_int16 (d->file, d->cells[i].base) ||            !file_write_int16 (d->file, d->cells[i].check))        {            return -1;        }    }    d->is_dirty = FALSE;    return 0;}TrieIndexda_get_root (const DArray *d){    /* can be calculated value for multi-index trie */    return 2;}TrieIndexda_get_base (const DArray *d, TrieIndex s){    return (s < d->num_cells) ? d->cells[s].base : TRIE_INDEX_ERROR;}TrieIndexda_get_check (const DArray *d, TrieIndex s){    return (s < d->num_cells) ? d->cells[s].check : TRIE_INDEX_ERROR;}voidda_set_base (DArray *d, TrieIndex s, TrieIndex val){    if (s < d->num_cells) {        d->cells[s].base = val;        d->is_dirty = TRUE;    }}voidda_set_check (DArray *d, TrieIndex s, TrieIndex val){    if (s < d->num_cells) {        d->cells[s].check = val;        d->is_dirty = TRUE;    }}Boolda_walk (DArray *d, TrieIndex *s, TrieChar c){    TrieIndex   next;    next = da_get_base (d, *s) + c;    if (da_get_check (d, next) == *s) {        *s = next;        return TRUE;    }    return FALSE;}TrieIndexda_insert_branch (DArray *d, TrieIndex s, TrieChar c){    TrieIndex   base, next;    base = da_get_base (d, s);    if (base > 0) {        next = da_get_base (d, s) + c;        /* if already there, do not actually insert */        if (da_get_check (d, next) == s)            return next;        if (!da_check_free_cell (d, next)) {            Symbols    *symbols;            TrieIndex   new_base;            /* relocate BASE[s] */            symbols = da_output_symbols (d, s);            symbols_add (symbols, c);            new_base = da_find_free_base (d, symbols);            symbols_free (symbols);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -