/* -*- 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 void
symbols_free (Symbols *syms)
{
free (syms);
}
static void
symbols_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 0xDAFD
DArray *
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;
}
int
da_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;
}
int
da_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;
}
TrieIndex
da_get_root (const DArray *d)
{
/* can be calculated value for multi-index trie */
return 2;
}
TrieIndex
da_get_base (const DArray *d, TrieIndex s)
{
return (s < d->num_cells) ? d->cells[s].base : TRIE_INDEX_ERROR;
}
TrieIndex
da_get_check (const DArray *d, TrieIndex s)
{
return (s < d->num_cells) ? d->cells[s].check : TRIE_INDEX_ERROR;
}
void
da_set_base (DArray *d, TrieIndex s, TrieIndex val)
{
if (s < d->num_cells) {
d->cells[s].base = val;
d->is_dirty = TRUE;
}
}
void
da_set_check (DArray *d, TrieIndex s, TrieIndex val)
{
if (s < d->num_cells) {
d->cells[s].check = val;
d->is_dirty = TRUE;
}
}
Bool
da_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;
}
TrieIndex
da_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);
da_relocate_base (d, s, new_base);
next = new_base + c;
}
} else {
Symbols *symbols;
TrieIndex new_base;
symbols = symbols_new ();
symbols_add (symbols, c);
new_base = da_find_free_base (d, symbols);
symbols_free (symbols);
da_set_base (d, s, new_base);
next = new_base + c;
}
da_alloc
没有合适的资源?快使用搜索试试~ 我知道了~
libdatrie-0.1.0.tar.gz_TRIE_libdatr_libdatrie_trie 数组
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 22 浏览量
2022-09-22
18:09:00
上传
评论
收藏 335KB GZ 举报
温馨提示
共41个文件
h:8个
c:7个
in:7个
介绍trie数组的算法实现,国外大牛写的,很好
资源推荐
资源详情
资源评论
收起资源包目录
libdatrie-0.1.0.tar.gz (41个子文件)
libdatrie-0.1.0
tools
Makefile.am 137B
Makefile.in 14KB
trietool.c 8KB
config.h.in 2KB
datrie
tail.c 8KB
darray.c 15KB
triedefs.h 1021B
sb-trie.c 6KB
alpha-map.h 837B
trie.c 10KB
tail.h 6KB
darray.h 6KB
Makefile.am 378B
Makefile.in 16KB
fileutils.c 2KB
typedefs.h 2KB
fileutils.h 815B
trie.h 7KB
sb-trie.h 7KB
alpha-map.c 4KB
depcomp 16KB
aclocal.m4 254KB
config.guess 43KB
Makefile.am 91B
config.sub 32KB
README 1KB
Makefile.in 20KB
INSTALL 9KB
missing 11KB
install-sh 9KB
AUTHORS 49B
doc
Doxyfile.in 10KB
Makefile.am 425B
Makefile.in 9KB
configure 697KB
datrie.pc.in 216B
ltmain.sh 192KB
NEWS 131B
ChangeLog 9KB
COPYING 26KB
configure.ac 2KB
共 41 条
- 1
资源评论
小贝德罗
- 粉丝: 68
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功