Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libloc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
libloc
Commits
d87fd7a3
Commit
d87fd7a3
authored
Nov 12, 2020
by
Michael Tremer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
database: Add option to return networks flattened
Signed-off-by:
Michael Tremer
<
michael.tremer@ipfire.org
>
parent
add5bb65
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
143 additions
and
31 deletions
+143
-31
src/database.c
src/database.c
+143
-31
No files found.
src/database.c
View file @
d87fd7a3
...
...
@@ -118,6 +118,9 @@ struct loc_database_enumerator {
struct
loc_node_stack
network_stack
[
MAX_STACK_DEPTH
];
int
network_stack_depth
;
unsigned
int
*
networks_visited
;
// For subnet search
struct
loc_network_list
*
stack
;
};
static
int
loc_database_read_magic
(
struct
loc_database
*
db
)
{
...
...
@@ -935,6 +938,26 @@ LOC_EXPORT int loc_database_get_country(struct loc_database* db,
// Enumerator
static
void
loc_database_enumerator_free
(
struct
loc_database_enumerator
*
enumerator
)
{
DEBUG
(
enumerator
->
ctx
,
"Releasing database enumerator %p
\n
"
,
enumerator
);
// Release all references
loc_database_unref
(
enumerator
->
db
);
loc_unref
(
enumerator
->
ctx
);
if
(
enumerator
->
string
)
free
(
enumerator
->
string
);
// Free network search
free
(
enumerator
->
networks_visited
);
// Free subnet stack
if
(
enumerator
->
stack
)
loc_network_list_unref
(
enumerator
->
stack
);
free
(
enumerator
);
}
LOC_EXPORT
int
loc_database_enumerator_new
(
struct
loc_database_enumerator
**
enumerator
,
struct
loc_database
*
db
,
enum
loc_database_enumerator_mode
mode
,
int
flags
)
{
struct
loc_database_enumerator
*
e
=
calloc
(
1
,
sizeof
(
*
e
));
...
...
@@ -951,10 +974,16 @@ LOC_EXPORT int loc_database_enumerator_new(struct loc_database_enumerator** enum
e
->
flatten
=
(
flags
&
LOC_DB_ENUMERATOR_FLAGS_FLATTEN
);
// Initialise graph search
//e->network_stack[++e->network_stack_depth] = 0;
e
->
network_stack_depth
=
1
;
e
->
networks_visited
=
calloc
(
db
->
network_nodes_count
,
sizeof
(
*
e
->
networks_visited
));
// Allocate stack
int
r
=
loc_network_list_new
(
e
->
ctx
,
&
e
->
stack
);
if
(
r
)
{
loc_database_enumerator_free
(
e
);
return
r
;
}
DEBUG
(
e
->
ctx
,
"Database enumerator object allocated at %p
\n
"
,
e
);
*
enumerator
=
e
;
...
...
@@ -967,22 +996,6 @@ LOC_EXPORT struct loc_database_enumerator* loc_database_enumerator_ref(struct lo
return
enumerator
;
}
static
void
loc_database_enumerator_free
(
struct
loc_database_enumerator
*
enumerator
)
{
DEBUG
(
enumerator
->
ctx
,
"Releasing database enumerator %p
\n
"
,
enumerator
);
// Release all references
loc_database_unref
(
enumerator
->
db
);
loc_unref
(
enumerator
->
ctx
);
if
(
enumerator
->
string
)
free
(
enumerator
->
string
);
// Free network search
free
(
enumerator
->
networks_visited
);
free
(
enumerator
);
}
LOC_EXPORT
struct
loc_database_enumerator
*
loc_database_enumerator_unref
(
struct
loc_database_enumerator
*
enumerator
)
{
if
(
!
enumerator
)
return
NULL
;
...
...
@@ -1116,17 +1129,13 @@ static int loc_database_enumerator_stack_push_node(
return
0
;
}
LOC_EXPORT
int
loc_database_enumerator_next_network
(
struct
loc_database_enumerator
*
enumerator
,
struct
loc_network
**
network
)
{
// Reset network
*
network
=
NULL
;
// Do not do anything if not in network mode
if
(
enumerator
->
mode
!=
LOC_DB_ENUMERATE_NETWORKS
)
static
int
__loc_database_enumerator_next_network
(
struct
loc_database_enumerator
*
enumerator
,
struct
loc_network
**
network
,
int
filter
)
{
// Return top element from the stack
*
network
=
loc_network_list_pop
(
enumerator
->
stack
);
if
(
*
network
)
return
0
;
int
r
;
DEBUG
(
enumerator
->
ctx
,
"Called with a stack of %u nodes
\n
"
,
enumerator
->
network_stack_depth
);
...
...
@@ -1155,7 +1164,7 @@ LOC_EXPORT int loc_database_enumerator_next_network(
enumerator
->
db
->
network_nodes_v1
+
node
->
offset
;
// Add edges to stack
r
=
loc_database_enumerator_stack_push_node
(
enumerator
,
int
r
=
loc_database_enumerator_stack_push_node
(
enumerator
,
be32toh
(
n
->
one
),
1
,
node
->
depth
+
1
);
if
(
r
)
...
...
@@ -1181,6 +1190,10 @@ LOC_EXPORT int loc_database_enumerator_next_network(
if
(
r
)
return
r
;
// Return all networks when the filter is disabled
if
(
!
filter
)
return
0
;
// Check if we are interested in this network
// Skip if the family does not match
...
...
@@ -1223,12 +1236,111 @@ LOC_EXPORT int loc_database_enumerator_next_network(
}
// Reached the end of the search
return
0
;
}
// Mark all nodes as non-visited
for
(
unsigned
int
i
=
0
;
i
<
enumerator
->
db
->
network_nodes_count
;
i
++
)
enumerator
->
networks_visited
[
i
]
=
0
;
static
int
__loc_database_enumerator_next_network_flattened
(
struct
loc_database_enumerator
*
enumerator
,
struct
loc_network
**
network
)
{
// Fetch the next network
int
r
=
__loc_database_enumerator_next_network
(
enumerator
,
network
,
1
);
if
(
r
)
return
r
;
// End if we could not read another network
if
(
!*
network
)
return
0
;
struct
loc_network
*
subnet
=
NULL
;
struct
loc_network_list
*
subnets
;
// Create a list with all subnets
r
=
loc_network_list_new
(
enumerator
->
ctx
,
&
subnets
);
if
(
r
)
return
r
;
// Search all subnets from the database
while
(
1
)
{
// Fetch the next network in line
r
=
__loc_database_enumerator_next_network
(
enumerator
,
&
subnet
,
0
);
if
(
r
)
goto
END
;
// End if we did not receive another subnet
if
(
!
subnet
)
break
;
// Collect all subnets in a list
if
(
loc_network_is_subnet
(
*
network
,
subnet
))
{
r
=
loc_network_list_push
(
subnets
,
subnet
);
if
(
r
)
goto
END
;
loc_network_unref
(
subnet
);
continue
;
}
// If this is not a subnet, we push it back onto the stack and break
r
=
loc_network_list_push
(
enumerator
->
stack
,
subnet
);
if
(
r
)
goto
END
;
loc_network_unref
(
subnet
);
break
;
}
DEBUG
(
enumerator
->
ctx
,
"Found %zu subnet(s)
\n
"
,
loc_network_list_size
(
subnets
));
// We can abort here if the network has no subnets
if
(
loc_network_list_empty
(
subnets
))
{
loc_network_list_unref
(
subnets
);
return
0
;
}
// If the network has any subnets, we will break it into smaller parts
// without the subnets.
struct
loc_network_list
*
excluded
=
loc_network_exclude_list
(
*
network
,
subnets
);
if
(
!
excluded
||
loc_network_list_empty
(
excluded
))
{
r
=
1
;
goto
END
;
}
// Sort the result
loc_network_list_sort
(
excluded
);
// Reverse the list
loc_network_list_reverse
(
excluded
);
// Replace network with the first one
loc_network_unref
(
*
network
);
*
network
=
loc_network_list_pop
(
excluded
);
// Push the rest onto the stack
loc_network_list_merge
(
enumerator
->
stack
,
excluded
);
loc_network_list_unref
(
excluded
);
END:
if
(
subnet
)
loc_network_unref
(
subnet
);
loc_network_list_unref
(
subnets
);
return
r
;
}
LOC_EXPORT
int
loc_database_enumerator_next_network
(
struct
loc_database_enumerator
*
enumerator
,
struct
loc_network
**
network
)
{
// Do not do anything if not in network mode
if
(
enumerator
->
mode
!=
LOC_DB_ENUMERATE_NETWORKS
)
return
0
;
// Flatten output?
if
(
enumerator
->
flatten
)
return
__loc_database_enumerator_next_network_flattened
(
enumerator
,
network
);
return
__loc_database_enumerator_next_network
(
enumerator
,
network
,
1
);
}
LOC_EXPORT
int
loc_database_enumerator_next_country
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment