Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/ip_t/ptopen.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2000-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* Phong Vo <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
23
/*
24
* pt handle operations
25
*
26
* Glenn Fowler
27
* AT&T Research
28
*/
29
30
#include "ptlib.h"
31
32
/*
33
* order by prefix
34
*/
35
36
static int
37
byprefix(Dt_t* dt, register Ptprefix_t* a, register Ptprefix_t* b, Dtdisc_t* disc)
38
{
39
NoP(dt);
40
NoP(disc);
41
42
if (a->max < b->min)
43
return -1;
44
if (a->min > b->max)
45
return 1;
46
return 0;
47
}
48
49
static void*
50
makef(Dt_t* dt, register Ptprefix_t* a, Dtdisc_t* disc)
51
{
52
register Ptprefix_t* b;
53
54
if (b = oldof(0, Ptprefix_t, 1, 0))
55
{
56
b->min = a->min;
57
b->max = a->max;
58
b->data.pointer = 0;
59
}
60
return b;
61
}
62
63
static void
64
freef(Dt_t* dt, Ptprefix_t* a, Dtdisc_t* disc)
65
{
66
free(a);
67
}
68
69
/*
70
* open a new table
71
*/
72
73
Pt_t*
74
ptopen(Ptdisc_t* disc)
75
{
76
Pt_t* a;
77
78
static Dtdisc_t prefixdisc;
79
80
prefixdisc.link = offsetof(Ptprefix_t, link);
81
prefixdisc.comparf = (Dtcompar_f)byprefix;
82
prefixdisc.makef = (Dtmake_f)makef;
83
prefixdisc.freef = (Dtfree_f)freef;
84
if (!(a = newof(0, Pt_t, 1, 0)) || !(a->dict = dtopen(&prefixdisc, Dtoset)))
85
{
86
if (disc->errorf)
87
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
88
if (a)
89
free(a);
90
return 0;
91
}
92
a->disc = disc;
93
return a;
94
}
95
96
/*
97
* close a table
98
*/
99
100
int
101
ptclose(Pt_t* a)
102
{
103
if (!a)
104
return -1;
105
dtclose(a->dict);
106
free(a);
107
return 0;
108
}
109
110
/*
111
* insert prefix range min..max into tab
112
* prefix pointer returned on success
113
*/
114
115
Ptprefix_t*
116
ptinsert(Pt_t* tab, Ptaddr_t min, Ptaddr_t max)
117
{
118
register Ptprefix_t* xp;
119
register Ptprefix_t* pp;
120
Ptprefix_t key;
121
122
tab->entries++;
123
key.min = key.max = min ? (min - 1) : min;
124
if (!(xp = (Ptprefix_t*)dtsearch(tab->dict, &key)))
125
xp = (Ptprefix_t*)dtnext(tab->dict, &key);
126
key.min = min;
127
key.max = max;
128
pp = 0;
129
if (xp)
130
{
131
if (key.min >= xp->min && key.max <= xp->max)
132
return xp;
133
if (key.max >= (xp->min ? (xp->min - 1) : 0))
134
{
135
if (key.min > xp->min)
136
key.min = xp->min;
137
do
138
{
139
max = xp->max;
140
pp = xp;
141
xp = (Ptprefix_t*)dtnext(tab->dict, xp);
142
dtdelete(tab->dict, pp);
143
} while (xp && key.max >= (xp->min - 1));
144
if (key.max < max)
145
key.max = max;
146
}
147
}
148
return (Ptprefix_t*)dtinsert(tab->dict, &key);
149
}
150
151
/*
152
* delete prefix range min..max from tab
153
* 0 returned on success
154
*/
155
156
int
157
ptdelete(Pt_t* tab, Ptaddr_t min, Ptaddr_t max)
158
{
159
register Ptprefix_t* xp;
160
Ptprefix_t key;
161
Ptprefix_t cur;
162
163
tab->entries++;
164
key.min = min;
165
key.max = max;
166
if (xp = (Ptprefix_t*)dtsearch(tab->dict, &key))
167
{
168
do
169
{
170
cur.min = xp->min;
171
cur.max = xp->max;
172
dtdelete(tab->dict, xp);
173
if (key.min > cur.min)
174
{
175
max = cur.max;
176
cur.max = key.min - 1;
177
if (!dtinsert(tab->dict, &cur))
178
goto bad;
179
if (key.max < max)
180
{
181
cur.min = key.max + 1;
182
cur.max = max;
183
if (!dtinsert(tab->dict, &cur))
184
goto bad;
185
break;
186
}
187
}
188
else if (key.max < xp->max)
189
{
190
xp->min = key.max + 1;
191
if (!dtinsert(tab->dict, xp))
192
goto bad;
193
}
194
} while (xp = (Ptprefix_t*)dtnext(tab->dict, xp));
195
}
196
return 0;
197
bad:
198
if (tab->disc->errorf)
199
(*tab->disc->errorf)(NiL, tab->disc, ERROR_SYSTEM|2, "out of space");
200
return -1;
201
}
202
203