-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmergetree.h
120 lines (103 loc) · 2.99 KB
/
mergetree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#ifndef _MERGETREESTRUCT_
#define _MERGETREESTRUCT_
typedef struct {
mtree *tree;
RAG *rag;
struct xvimage *labels;
int32_t *altitudes;
float *weights;
int cs;
int rs;
} MergeTree;
#endif
#ifndef _MERGETREE_
#define _MERGETREE_
// create a proper Lua class to represent a merge tree
#define MT "imgraph.MergeTree"
static MergeTree *lua_toMergeTree (lua_State *L, int index)
{
MergeTree *mt = (MergeTree *)lua_touserdata(L, index);
if (mt == NULL) luaL_typerror(L, index, MT);
return mt;
}
static MergeTree *lua_checkMergeTree (lua_State *L, int index)
{
MergeTree *mt;
luaL_checktype(L, index, LUA_TUSERDATA);
mt = (MergeTree *)luaL_checkudata(L, index, MT);
if (mt == NULL) luaL_typerror(L, index, MT);
return mt;
}
static MergeTree *lua_pushMergeTree (lua_State *L)
{
MergeTree *mt = (MergeTree *)lua_newuserdata(L, sizeof(MergeTree));
mt->tree = NULL;
mt->labels = NULL;
mt->rag = NULL;
mt->altitudes = NULL;
mt->weights = NULL;
mt->cs = 0;
mt->rs = 0;
luaL_getmetatable(L, MT);
lua_setmetatable(L, -2);
return mt;
}
static int MergeTree_gc (lua_State *L)
{
MergeTree *t = lua_toMergeTree(L, 1);
if (t->tree) mergeTreeFree(t->tree);
if (t->labels) freeimage(t->labels);
if (t->rag) termineRAG(t->rag);
if (t->altitudes) free(t->altitudes);
if (t->weights) free(t->weights);
return 0;
}
static int MergeTree_tostring (lua_State *L)
{
MergeTree *t = lua_toMergeTree(L, 1);
char *cstr = (char *)malloc(10*1024);
char *str = cstr;
str += sprintf(str, "<%s>\n", MT);
int32_t i;
JCsoncell *s;
JCctree *CT = t->tree->CT;
str += sprintf(str, " + root: %d ; nbnodes: %d ; nbsoncells: %d", CT->root, CT->nbnodes, CT->nbsoncells);
for (i = 0; i < CT->nbnodes; i++)
{
str += sprintf(str, "\n");
str += sprintf(str, " - node: %d ; level %d ; nbsons: %d ; father: %d ; ",
i, CT->tabnodes[i].data, CT->tabnodes[i].nbsons, CT->tabnodes[i].father);
if (t->weights) {
str += sprintf(str, "weight: %f ; ", t->weights[i]);
}
if (CT->tabnodes[i].nbsons > 0) {
str += sprintf(str, "sons: ");
for (s = CT->tabnodes[i].sonlist; s != NULL; s = s->next)
str += sprintf(str, "%d ", s->son);
}
if ((str-cstr) > 9*1024) {
str += sprintf(str, "\n ... ");
break;
}
}
lua_pushfstring(L, "%s", cstr);
free(cstr);
return 1;
}
static const luaL_reg MergeTree_meta[] = {
{"__gc", MergeTree_gc},
{"__tostring", MergeTree_tostring},
{0, 0}
};
static int MergeTree_register (lua_State *L)
{
luaL_newmetatable(L, MT); /* create metatable for Graph,
and add it to the Lua registry */
luaL_openlib(L, 0, MergeTree_meta, 0); /* fill metatable */
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* hide metatable:
metatable.__metatable = methods */
lua_pop(L, 1); /* drop metatable */
}
#endif