Skip to content

Commit 265b406

Browse files
Reduce I/O
1 parent 86f1608 commit 265b406

1 file changed

Lines changed: 155 additions & 65 deletions

File tree

ip2location.erl

Lines changed: 155 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@
2222
elevation = 0,
2323
usagetype = "-"
2424
}).
25+
-define(IF(Cond), (case (Cond) of true -> (0); false -> (1) end)).
2526

2627
apiversion() ->
27-
"8.1.1".
28+
"8.2.0".
2829

2930
getapiversion() ->
3031
io:format("API Version: ~p~n", [apiversion()]).
@@ -41,12 +42,19 @@ readuint(S, StartPos, Len) ->
4142
binary:decode_unsigned(Data, little)
4243
end.
4344

45+
readuintrow(R, StartPos, Len) ->
46+
Data = binary:part(R, StartPos, Len),
47+
binary:decode_unsigned(Data, little).
48+
4449
readuint8(S, StartPos) ->
4550
readuint(S, StartPos, 1).
4651

4752
readuint32(S, StartPos) ->
4853
readuint(S, StartPos, 4).
4954

55+
readuint32row(R, StartPos) ->
56+
readuintrow(R, StartPos, 4).
57+
5058
readuint128(S, StartPos) ->
5159
readuint(S, StartPos, 16).
5260

@@ -64,14 +72,19 @@ readstr(S, StartPos) ->
6472
end
6573
end.
6674

67-
readfloat(S, StartPos) ->
68-
case file:pread(S, StartPos - 1, 4) of
69-
eof ->
70-
ok;
71-
{ok, Data} ->
72-
<<F:32/float-little>> = Data,
73-
F
74-
end.
75+
% readfloat(S, StartPos) ->
76+
% case file:pread(S, StartPos - 1, 4) of
77+
% eof ->
78+
% ok;
79+
% {ok, Data} ->
80+
% <<F:32/float-little>> = Data,
81+
% F
82+
% end.
83+
84+
readfloatrow(R, StartPos) ->
85+
Data = binary:part(R, StartPos, 4),
86+
<<F:32/float-little>> = Data,
87+
F.
7588

7689
input(InputFile) ->
7790
case file:open(InputFile, [read, binary, raw]) of
@@ -122,45 +135,90 @@ new(InputFile) ->
122135
ets:insert(mymeta, {ipv4columnsize, Ipv4columnsize}),
123136
ets:insert(mymeta, {ipv6columnsize, Ipv6columnsize}).
124137

125-
readcolcountry(S, Dbtype, Rowoffset, Col) ->
138+
% readcolcountry(S, Dbtype, Rowoffset, Col) ->
139+
% X = "This parameter is unavailable for selected data file. Please upgrade the data file.",
140+
% case lists:nth(Dbtype, Col) of
141+
% 0 ->
142+
% {X, X};
143+
% Colpos ->
144+
% Coloffset = (Colpos - 1) bsl 2,
145+
% X0 = readuint32(S, Rowoffset + Coloffset),
146+
% X1 = readstr(S, X0),
147+
% X2 = readstr(S, X0 + 3),
148+
% {X1, X2}
149+
% end.
150+
151+
readcolcountryrow(S, R, Dbtype, Col) ->
126152
X = "This parameter is unavailable for selected data file. Please upgrade the data file.",
127153
case lists:nth(Dbtype, Col) of
128154
0 ->
129155
{X, X};
130156
Colpos ->
131-
Coloffset = (Colpos - 1) bsl 2,
132-
X0 = readuint32(S, Rowoffset + Coloffset),
157+
Coloffset = (Colpos - 2) bsl 2,
158+
X0 = readuint32row(R, Coloffset),
133159
X1 = readstr(S, X0),
134160
X2 = readstr(S, X0 + 3),
135161
{X1, X2}
136162
end.
137163

138-
readcolstring(S, Dbtype, Rowoffset, Col) ->
164+
% readcolstring(S, Dbtype, Rowoffset, Col) ->
165+
% case lists:nth(Dbtype, Col) of
166+
% 0 ->
167+
% "This parameter is unavailable for selected data file. Please upgrade the data file.";
168+
% Colpos ->
169+
% Coloffset = (Colpos - 1) bsl 2,
170+
% readstr(S, readuint32(S, Rowoffset + Coloffset))
171+
% end.
172+
173+
readcolstringrow(S, R, Dbtype, Col) ->
139174
case lists:nth(Dbtype, Col) of
140175
0 ->
141176
"This parameter is unavailable for selected data file. Please upgrade the data file.";
142177
Colpos ->
143-
Coloffset = (Colpos - 1) bsl 2,
144-
readstr(S, readuint32(S, Rowoffset + Coloffset))
178+
Coloffset = (Colpos - 2) bsl 2,
179+
readstr(S, readuint32row(R, Coloffset))
145180
end.
146-
147181

148-
readcolfloat(S, Dbtype, Rowoffset, Col) ->
182+
% readcolfloat(S, Dbtype, Rowoffset, Col) ->
183+
% case lists:nth(Dbtype, Col) of
184+
% 0 ->
185+
% 0.0;
186+
% Colpos ->
187+
% Coloffset = (Colpos - 1) bsl 2,
188+
% round(readfloat(S, Rowoffset + Coloffset), 6)
189+
% end.
190+
191+
readcolfloatrow(R, Dbtype, Col) ->
149192
case lists:nth(Dbtype, Col) of
150193
0 ->
151194
0.0;
152195
Colpos ->
153-
Coloffset = (Colpos - 1) bsl 2,
154-
round(readfloat(S, Rowoffset + Coloffset), 6)
196+
Coloffset = (Colpos - 2) bsl 2,
197+
round(readfloatrow(R, Coloffset), 6)
155198
end.
156199

157-
readcolfloatstring(S, Dbtype, Rowoffset, Col) ->
200+
% readcolfloatstring(S, Dbtype, Rowoffset, Col) ->
201+
% case lists:nth(Dbtype, Col) of
202+
% 0 ->
203+
% 0.0;
204+
% Colpos ->
205+
% Coloffset = (Colpos - 1) bsl 2,
206+
% N = readstr(S, readuint32(S, Rowoffset + Coloffset)),
207+
% case string:to_float(N) of
208+
% {error,no_float} ->
209+
% list_to_integer(N);
210+
% {F,_Rest} ->
211+
% F
212+
% end
213+
% end.
214+
215+
readcolfloatstringrow(S, R, Dbtype, Col) ->
158216
case lists:nth(Dbtype, Col) of
159217
0 ->
160218
0.0;
161219
Colpos ->
162-
Coloffset = (Colpos - 1) bsl 2,
163-
N = readstr(S, readuint32(S, Rowoffset + Coloffset)),
220+
Coloffset = (Colpos - 2) bsl 2,
221+
N = readstr(S, readuint32row(R, Coloffset)),
164222
case string:to_float(N) of
165223
{error,no_float} ->
166224
list_to_integer(N);
@@ -190,48 +248,78 @@ readrecord(S, Dbtype, Rowoffset) ->
190248
Elevation_position = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 19, 0, 19],
191249
Usagetype_position = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 20],
192250

193-
{Country_short, Country_long} = readcolcountry(S, Dbtype, Rowoffset, Country_position),
194-
Region = readcolstring(S, Dbtype, Rowoffset, Region_position),
195-
City = readcolstring(S, Dbtype, Rowoffset, City_position),
196-
Isp = readcolstring(S, Dbtype, Rowoffset, Isp_position),
197-
Latitude = readcolfloat(S, Dbtype, Rowoffset, Latitude_position),
198-
Longitude = readcolfloat(S, Dbtype, Rowoffset, Longitude_position),
199-
Domain = readcolstring(S, Dbtype, Rowoffset, Domain_position),
200-
Zipcode = readcolstring(S, Dbtype, Rowoffset, Zipcode_position),
201-
Timezone = readcolstring(S, Dbtype, Rowoffset, Timezone_position),
202-
Netspeed = readcolstring(S, Dbtype, Rowoffset, Netspeed_position),
203-
Iddcode = readcolstring(S, Dbtype, Rowoffset, Iddcode_position),
204-
Areacode = readcolstring(S, Dbtype, Rowoffset, Areacode_position),
205-
Weatherstationcode = readcolstring(S, Dbtype, Rowoffset, Weatherstationcode_position),
206-
Weatherstationname = readcolstring(S, Dbtype, Rowoffset, Weatherstationname_position),
207-
Mcc = readcolstring(S, Dbtype, Rowoffset, Mcc_position),
208-
Mnc = readcolstring(S, Dbtype, Rowoffset, Mnc_position),
209-
Mobilebrand = readcolstring(S, Dbtype, Rowoffset, Mobilebrand_position),
210-
Elevation = readcolfloatstring(S, Dbtype, Rowoffset, Elevation_position),
211-
Usagetype = readcolstring(S, Dbtype, Rowoffset, Usagetype_position),
251+
Cols = ?IF(lists:nth(Dbtype, Country_position) == 0) + ?IF(lists:nth(Dbtype, Region_position) == 0) + ?IF(lists:nth(Dbtype, City_position) == 0) + ?IF(lists:nth(Dbtype, Isp_position) == 0) + ?IF(lists:nth(Dbtype, Latitude_position) == 0) + ?IF(lists:nth(Dbtype, Longitude_position) == 0) + ?IF(lists:nth(Dbtype, Domain_position) == 0) + ?IF(lists:nth(Dbtype, Zipcode_position) == 0) + ?IF(lists:nth(Dbtype, Timezone_position) == 0) + ?IF(lists:nth(Dbtype, Netspeed_position) == 0) + ?IF(lists:nth(Dbtype, Iddcode_position) == 0) + ?IF(lists:nth(Dbtype, Areacode_position) == 0) + ?IF(lists:nth(Dbtype, Weatherstationcode_position) == 0) + ?IF(lists:nth(Dbtype, Weatherstationname_position) == 0) + ?IF(lists:nth(Dbtype, Mcc_position) == 0) + ?IF(lists:nth(Dbtype, Mnc_position) == 0) + ?IF(lists:nth(Dbtype, Mobilebrand_position) == 0) + ?IF(lists:nth(Dbtype, Elevation_position) == 0) + ?IF(lists:nth(Dbtype, Usagetype_position) == 0),
252+
Rowlength = Cols bsl 2,
212253

213-
#ip2locationrecord{
214-
country_short = Country_short,
215-
country_long = Country_long,
216-
region = Region,
217-
city = City,
218-
isp = Isp,
219-
latitude = Latitude,
220-
longitude = Longitude,
221-
domain = Domain,
222-
zipcode = Zipcode,
223-
timezone = Timezone,
224-
netspeed = Netspeed,
225-
iddcode = Iddcode,
226-
areacode = Areacode,
227-
weatherstationcode = Weatherstationcode,
228-
weatherstationname = Weatherstationname,
229-
mcc = Mcc,
230-
mnc = Mnc,
231-
mobilebrand = Mobilebrand,
232-
elevation = Elevation,
233-
usagetype = Usagetype
234-
}.
254+
case file:pread(S, Rowoffset - 1, Rowlength) of
255+
eof ->
256+
#ip2locationrecord{};
257+
{ok, Data} ->
258+
R = Data,
259+
260+
% {Country_short, Country_long} = readcolcountry(S, Dbtype, Rowoffset, Country_position),
261+
% Region = readcolstring(S, Dbtype, Rowoffset, Region_position),
262+
% City = readcolstring(S, Dbtype, Rowoffset, City_position),
263+
% Isp = readcolstring(S, Dbtype, Rowoffset, Isp_position),
264+
% Latitude = readcolfloat(S, Dbtype, Rowoffset, Latitude_position),
265+
% Longitude = readcolfloat(S, Dbtype, Rowoffset, Longitude_position),
266+
% Domain = readcolstring(S, Dbtype, Rowoffset, Domain_position),
267+
% Zipcode = readcolstring(S, Dbtype, Rowoffset, Zipcode_position),
268+
% Timezone = readcolstring(S, Dbtype, Rowoffset, Timezone_position),
269+
% Netspeed = readcolstring(S, Dbtype, Rowoffset, Netspeed_position),
270+
% Iddcode = readcolstring(S, Dbtype, Rowoffset, Iddcode_position),
271+
% Areacode = readcolstring(S, Dbtype, Rowoffset, Areacode_position),
272+
% Weatherstationcode = readcolstring(S, Dbtype, Rowoffset, Weatherstationcode_position),
273+
% Weatherstationname = readcolstring(S, Dbtype, Rowoffset, Weatherstationname_position),
274+
% Mcc = readcolstring(S, Dbtype, Rowoffset, Mcc_position),
275+
% Mnc = readcolstring(S, Dbtype, Rowoffset, Mnc_position),
276+
% Mobilebrand = readcolstring(S, Dbtype, Rowoffset, Mobilebrand_position),
277+
% Elevation = readcolfloatstring(S, Dbtype, Rowoffset, Elevation_position),
278+
% Usagetype = readcolstring(S, Dbtype, Rowoffset, Usagetype_position),
279+
280+
{Country_short, Country_long} = readcolcountryrow(S, R, Dbtype, Country_position),
281+
Region = readcolstringrow(S, R, Dbtype, Region_position),
282+
City = readcolstringrow(S, R, Dbtype, City_position),
283+
Isp = readcolstringrow(S, R, Dbtype, Isp_position),
284+
Latitude = readcolfloatrow(R, Dbtype, Latitude_position),
285+
Longitude = readcolfloatrow(R, Dbtype, Longitude_position),
286+
Domain = readcolstringrow(S, R, Dbtype, Domain_position),
287+
Zipcode = readcolstringrow(S, R, Dbtype, Zipcode_position),
288+
Timezone = readcolstringrow(S, R, Dbtype, Timezone_position),
289+
Netspeed = readcolstringrow(S, R, Dbtype, Netspeed_position),
290+
Iddcode = readcolstringrow(S, R, Dbtype, Iddcode_position),
291+
Areacode = readcolstringrow(S, R, Dbtype, Areacode_position),
292+
Weatherstationcode = readcolstringrow(S, R, Dbtype, Weatherstationcode_position),
293+
Weatherstationname = readcolstringrow(S, R, Dbtype, Weatherstationname_position),
294+
Mcc = readcolstringrow(S, R, Dbtype, Mcc_position),
295+
Mnc = readcolstringrow(S, R, Dbtype, Mnc_position),
296+
Mobilebrand = readcolstringrow(S, R, Dbtype, Mobilebrand_position),
297+
Elevation = readcolfloatstringrow(S, R, Dbtype, Elevation_position),
298+
Usagetype = readcolstringrow(S, R, Dbtype, Usagetype_position),
299+
300+
#ip2locationrecord{
301+
country_short = Country_short,
302+
country_long = Country_long,
303+
region = Region,
304+
city = City,
305+
isp = Isp,
306+
latitude = Latitude,
307+
longitude = Longitude,
308+
domain = Domain,
309+
zipcode = Zipcode,
310+
timezone = Timezone,
311+
netspeed = Netspeed,
312+
iddcode = Iddcode,
313+
areacode = Areacode,
314+
weatherstationcode = Weatherstationcode,
315+
weatherstationname = Weatherstationname,
316+
mcc = Mcc,
317+
mnc = Mnc,
318+
mobilebrand = Mobilebrand,
319+
elevation = Elevation,
320+
usagetype = Usagetype
321+
}
322+
end.
235323

236324
searchtree(S, Ipnum, Dbtype, Low, High, BaseAddr, Colsize, Iptype) ->
237325
if
@@ -253,9 +341,11 @@ searchtree(S, Ipnum, Dbtype, Low, High, BaseAddr, Colsize, Iptype) ->
253341
Ipnum >= Ipfrom andalso Ipnum < Ipto ->
254342
if
255343
Iptype == ipv4 ->
256-
readrecord(S, Dbtype + 1, Rowoffset);
344+
% readrecord(S, Dbtype + 1, Rowoffset);
345+
readrecord(S, Dbtype + 1, Rowoffset + 4);
257346
true ->
258-
readrecord(S, Dbtype + 1, Rowoffset + 12)
347+
% readrecord(S, Dbtype + 1, Rowoffset + 12)
348+
readrecord(S, Dbtype + 1, Rowoffset + 16)
259349
end;
260350
true ->
261351
if

0 commit comments

Comments
 (0)