1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2006, 2007 Guillaume Chazarain <guichaz@yahoo.fr>
21 from pysize
.core
.pysize_global_fs_cache
import get_dev_ino
23 # ['/path/to/file1', '/path/to/file2']
26 # {device: {inode: (size_to_subtract|DELETED)}}
27 DEV_INO_TO_SUBTRACT
= {}
31 def _get_subtracted(path
):
32 dev
, ino
= get_dev_ino(path
)
33 return DEV_INO_TO_SUBTRACT
.setdefault(dev
, {}).get(ino
, None)
35 def _iter_to_the_root(path
):
36 while path
not in ('/', ''):
37 yield get_dev_ino(path
), path
38 path
= os
.path
.dirname(path
)
40 def get_subtracted(path
):
41 if DEV_INO_TO_SUBTRACT
:
42 for dev_ino
, tmp_path
in _iter_to_the_root(path
):
43 if _get_subtracted(tmp_path
) is DELETED
:
45 subtracted
= _get_subtracted(path
)
46 if subtracted
is not None:
51 from pysize
.core
import compute_size
52 size
= compute_size
.slow(path
)
53 dev
, ino
= get_dev_ino(path
)
54 DEV_INO_TO_SUBTRACT
.setdefault(dev
, {})[ino
] = DELETED
55 for (dev
, ino
), path
in _iter_to_the_root(os
.path
.dirname(path
)):
56 inodes
= DEV_INO_TO_SUBTRACT
.setdefault(dev
, {})
57 subtract
= inodes
.get(ino
, 0)
59 inodes
[ino
] = subtract
61 # TODO: Deletion of hard links
64 for path
in node
.get_fullpaths():
65 subtract
= get_subtracted(path
)
66 if subtract
is not DELETED
:
67 TO_DELETE
.append(path
)
73 """Remove children if we have the parent"""
75 for i
in xrange(len(TO_DELETE
)):
76 parent
= os
.path
.dirname(TO_DELETE
[i
])
77 if get_subtracted(parent
) is DELETED
:
84 DEV_INO_TO_SUBTRACT
.clear()
85 for path
in TO_DELETE
:
88 def filter_deleted(paths
):
89 if DEV_INO_TO_SUBTRACT
:
90 def is_not_deleted(path
):
91 return get_subtracted(path
) is not DELETED
92 return filter(is_not_deleted
, paths
)
99 from pysize
.core
import compute_size
100 TO_DELETE
.remove(path
)
101 dev
, ino
= get_dev_ino(path
)
102 del DEV_INO_TO_SUBTRACT
[dev
][ino
]
103 size
= compute_size
.slow(path
, account_deletion
=False)
104 for (dev
, ino
), path
in _iter_to_the_root(os
.path
.dirname(path
)):
105 inodes
= DEV_INO_TO_SUBTRACT
[dev
]
106 if inodes
[ino
] == size
: