Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
N
nccf
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
702
Provoz
nccf
Commits
5929bf57
Commit
5929bf57
authored
3 years ago
by
Yorhel
Browse files
Options
Downloads
Patches
Plain Diff
Keep track of uncounted hard links to speed up refresh+delete operations
parent
ba14c093
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/model.zig
+29
-5
29 additions, 5 deletions
src/model.zig
with
29 additions
and
5 deletions
src/model.zig
+
29
−
5
View file @
5929bf57
...
@@ -134,7 +134,7 @@ pub const Entry = packed struct {
...
@@ -134,7 +134,7 @@ pub const Entry = packed struct {
l
.
next
=
d
.
key_ptr
.*
.
next
;
l
.
next
=
d
.
key_ptr
.*
.
next
;
d
.
key_ptr
.*
.
next
=
l
;
d
.
key_ptr
.*
.
next
=
l
;
}
}
inodes
.
addUncounted
(
l
);
}
}
var
it
:
?*
Dir
=
parent
;
var
it
:
?*
Dir
=
parent
;
...
@@ -173,10 +173,12 @@ pub const Entry = packed struct {
...
@@ -173,10 +173,12 @@ pub const Entry = packed struct {
d
.
value_ptr
.
nlink
=
0
;
d
.
value_ptr
.
nlink
=
0
;
if
(
l
.
next
==
l
)
{
if
(
l
.
next
==
l
)
{
_
=
inodes
.
map
.
remove
(
l
);
_
=
inodes
.
map
.
remove
(
l
);
_
=
inodes
.
uncounted
.
remove
(
l
);
inodes
.
total_blocks
=
saturateSub
(
inodes
.
total_blocks
,
self
.
blocks
);
inodes
.
total_blocks
=
saturateSub
(
inodes
.
total_blocks
,
self
.
blocks
);
}
else
{
}
else
{
if
(
d
.
key_ptr
.*
==
l
)
if
(
d
.
key_ptr
.*
==
l
)
d
.
key_ptr
.*
=
l
.
next
;
d
.
key_ptr
.*
=
l
.
next
;
inodes
.
addUncounted
(
l
.
next
);
// This is O(n), which in this context has the potential to
// This is O(n), which in this context has the potential to
// slow ncdu down to a crawl. But this function is only called
// slow ncdu down to a crawl. But this function is only called
// on refresh/delete operations and even then it's not common
// on refresh/delete operations and even then it's not common
...
@@ -343,6 +345,13 @@ pub const inodes = struct {
...
@@ -343,6 +345,13 @@ pub const inodes = struct {
// the hard links are not counted as part of the parent directories yet.
// the hard links are not counted as part of the parent directories yet.
pub
var
total_blocks
:
Blocks
=
0
;
pub
var
total_blocks
:
Blocks
=
0
;
// List of nodes in 'map' with !counted, to speed up addAllStats().
// If this list grows large relative to the number of nodes in 'map', then
// this list is cleared and uncounted_full is set instead, so that
// addAllStats() will do a full iteration over 'map'.
var
uncounted
=
std
.
HashMap
(
*
Link
,
void
,
HashContext
,
80
).
init
(
main
.
allocator
);
var
uncounted_full
=
true
;
// start with true for the initial scan
const
Inode
=
packed
struct
{
const
Inode
=
packed
struct
{
// Whether this Inode is counted towards the parent directories.
// Whether this Inode is counted towards the parent directories.
counted
:
bool
,
counted
:
bool
,
...
@@ -367,6 +376,15 @@ pub const inodes = struct {
...
@@ -367,6 +376,15 @@ pub const inodes = struct {
}
}
};
};
fn
addUncounted
(
l
:
*
Link
)
void
{
if
(
uncounted_full
)
return
;
if
(
uncounted
.
count
()
>
map
.
count
()
/
8
)
{
uncounted
.
clearAndFree
();
uncounted_full
=
true
;
}
else
(
uncounted
.
getOrPut
(
l
)
catch
unreachable
).
key_ptr
.*
=
l
;
}
// Add/remove this inode from the parent Dir sizes. When removing stats,
// Add/remove this inode from the parent Dir sizes. When removing stats,
// the list of *Links and their sizes and counts must be in the exact same
// the list of *Links and their sizes and counts must be in the exact same
// state as when the stats were added. Hence, any modification to the Link
// state as when the stats were added. Hence, any modification to the Link
...
@@ -419,11 +437,17 @@ pub const inodes = struct {
...
@@ -419,11 +437,17 @@ pub const inodes = struct {
}
}
}
}
// TODO: A version that doesn't have to iterate over the entire map, for
// smaller refresh/delete updates.
pub
fn
addAllStats
()
void
{
pub
fn
addAllStats
()
void
{
var
it
=
map
.
iterator
();
if
(
uncounted_full
)
{
while
(
it
.
next
())
|
e
|
setStats
(
e
,
true
);
var
it
=
map
.
iterator
();
while
(
it
.
next
())
|
e
|
setStats
(
e
,
true
);
}
else
{
var
it
=
uncounted
.
iterator
();
while
(
it
.
next
())
|
u
|
if
(
map
.
getEntry
(
u
.
key_ptr
.*
))
|
e
|
setStats
(
e
,
true
);
}
uncounted_full
=
false
;
if
(
uncounted
.
count
()
>
0
)
uncounted
.
clearAndFree
();
}
}
};
};
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment