1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/sync_file_system/subtree_set.h"
7 #include "base/logging.h"
8 #include "base/stl_util.h"
9 #include "storage/common/fileapi/file_system_util.h"
11 namespace sync_file_system
{
13 SubtreeSet::Node::Node()
14 : contained_as_subtree_root(false),
15 number_of_subtrees_below(0) {
18 SubtreeSet::Node::Node(bool contained_as_subtree_root
,
19 size_t number_of_subtrees_below
)
20 : contained_as_subtree_root(contained_as_subtree_root
),
21 number_of_subtrees_below(number_of_subtrees_below
) {
24 SubtreeSet::SubtreeSet() {}
25 SubtreeSet::~SubtreeSet() {}
27 bool SubtreeSet::IsDisjointWith(const base::FilePath
& subtree_root
) const {
28 base::FilePath::StringType normalized_subtree_root
=
29 storage::VirtualPath::GetNormalizedFilePath(subtree_root
);
31 // Check if |subtree_root| contains any of subtrees in the container.
32 if (ContainsKey(inclusive_ancestors_of_subtree_roots_
,
33 normalized_subtree_root
))
36 base::FilePath
path(normalized_subtree_root
);
37 while (!storage::VirtualPath::IsRootPath(path
)) {
38 path
= storage::VirtualPath::DirName(path
);
40 Subtrees::const_iterator found
=
41 inclusive_ancestors_of_subtree_roots_
.find(path
.value());
42 if (found
!= inclusive_ancestors_of_subtree_roots_
.end())
43 return !found
->second
.contained_as_subtree_root
;
49 bool SubtreeSet::insert(const base::FilePath
& subtree_root
) {
50 base::FilePath::StringType normalized_subtree_root
=
51 storage::VirtualPath::GetNormalizedFilePath(subtree_root
);
53 if (!IsDisjointWith(subtree_root
))
55 inclusive_ancestors_of_subtree_roots_
[normalized_subtree_root
]
58 base::FilePath
path(normalized_subtree_root
);
59 while (!storage::VirtualPath::IsRootPath(path
)) {
60 path
= storage::VirtualPath::DirName(path
);
61 DCHECK(!inclusive_ancestors_of_subtree_roots_
[path
.value()]
62 .contained_as_subtree_root
);
63 ++(inclusive_ancestors_of_subtree_roots_
[path
.value()]
64 .number_of_subtrees_below
);
70 bool SubtreeSet::erase(const base::FilePath
& subtree_root
) {
71 base::FilePath::StringType normalized_subtree_root
=
72 storage::VirtualPath::GetNormalizedFilePath(subtree_root
);
75 Subtrees::iterator found
=
76 inclusive_ancestors_of_subtree_roots_
.find(normalized_subtree_root
);
77 if (found
== inclusive_ancestors_of_subtree_roots_
.end() ||
78 !found
->second
.contained_as_subtree_root
)
81 DCHECK_EQ(1u, found
->second
.number_of_subtrees_below
);
82 inclusive_ancestors_of_subtree_roots_
.erase(found
);
85 base::FilePath
path(normalized_subtree_root
);
86 while (!storage::VirtualPath::IsRootPath(path
)) {
87 path
= storage::VirtualPath::DirName(path
);
89 Subtrees::iterator found
=
90 inclusive_ancestors_of_subtree_roots_
.find(path
.value());
91 if (found
== inclusive_ancestors_of_subtree_roots_
.end()) {
96 DCHECK(!found
->second
.contained_as_subtree_root
);
97 if (!--(found
->second
.number_of_subtrees_below
))
98 inclusive_ancestors_of_subtree_roots_
.erase(found
);
104 size_t SubtreeSet::size() const {
105 Subtrees::const_iterator found
=
106 inclusive_ancestors_of_subtree_roots_
.find(storage::VirtualPath::kRoot
);
107 if (found
== inclusive_ancestors_of_subtree_roots_
.end())
109 return found
->second
.number_of_subtrees_below
;
112 } // namespace sync_file_system