1a69a01cdSopenharmony_ci/*
2a69a01cdSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3a69a01cdSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a69a01cdSopenharmony_ci * you may not use this file except in compliance with the License.
5a69a01cdSopenharmony_ci * You may obtain a copy of the License at
6a69a01cdSopenharmony_ci *
7a69a01cdSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a69a01cdSopenharmony_ci *
9a69a01cdSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a69a01cdSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a69a01cdSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a69a01cdSopenharmony_ci * See the License for the specific language governing permissions and
13a69a01cdSopenharmony_ci * limitations under the License.
14a69a01cdSopenharmony_ci */
15a69a01cdSopenharmony_ci
16a69a01cdSopenharmony_ci#include "page_tree.h"
17a69a01cdSopenharmony_ci
18a69a01cdSopenharmony_ci#include "tree_manager.h"
19a69a01cdSopenharmony_ci
20a69a01cdSopenharmony_cinamespace OHOS {
21a69a01cdSopenharmony_cinamespace WuKong {
22a69a01cdSopenharmony_cinamespace {
23a69a01cdSopenharmony_ciconst uint8_t PAGE_COUNT_POSION = 50;
24a69a01cdSopenharmony_ciconst uint8_t PAGE_NODE_COUNT_POSION = 36;
25a69a01cdSopenharmony_ciconst uint8_t PAGE_BRANCH_COUNT_POSION = 28;
26a69a01cdSopenharmony_ciconst uint8_t PAGE_HEIGHT_POSION = 22;
27a69a01cdSopenharmony_ciconst uint8_t PAGE_TWO_LAYER_WIDTH_POSION = 14;
28a69a01cdSopenharmony_ciconst uint8_t PAGE_LAST_LAYER_WIDTH_POSION = 0;
29a69a01cdSopenharmony_ciuint64_t pageCount = 0;
30a69a01cdSopenharmony_ciuint64_t nodeCount = 0;
31a69a01cdSopenharmony_ciuint64_t branchCount = 0;
32a69a01cdSopenharmony_ciuint32_t layer = 0;
33a69a01cdSopenharmony_ciuint32_t height = 0;
34a69a01cdSopenharmony_ciuint32_t lastWidth = 0;
35a69a01cdSopenharmony_cibool g_isLeftBranch = false;
36a69a01cdSopenharmony_civoid RecursStatistics(std::shared_ptr<ComponentTree> parent)
37a69a01cdSopenharmony_ci{
38a69a01cdSopenharmony_ci    // all page node count Statistics
39a69a01cdSopenharmony_ci    pageCount++;
40a69a01cdSopenharmony_ci    uint32_t childCount = parent->GetChildren().size();
41a69a01cdSopenharmony_ci
42a69a01cdSopenharmony_ci    // layer pointer move to next
43a69a01cdSopenharmony_ci    layer++;
44a69a01cdSopenharmony_ci    if (childCount == 0) {
45a69a01cdSopenharmony_ci        // node Statistics
46a69a01cdSopenharmony_ci        nodeCount++;
47a69a01cdSopenharmony_ci    } else {
48a69a01cdSopenharmony_ci        // branch Statistics
49a69a01cdSopenharmony_ci        branchCount++;
50a69a01cdSopenharmony_ci        if (layer >= height) {
51a69a01cdSopenharmony_ci            // tree max height Statistics
52a69a01cdSopenharmony_ci            height++;
53a69a01cdSopenharmony_ci
54a69a01cdSopenharmony_ci            // last tree width.
55a69a01cdSopenharmony_ci            lastWidth = childCount;
56a69a01cdSopenharmony_ci        }
57a69a01cdSopenharmony_ci    }
58a69a01cdSopenharmony_ci
59a69a01cdSopenharmony_ci    // recurs child.
60a69a01cdSopenharmony_ci    for (auto child : parent->GetChildren()) {
61a69a01cdSopenharmony_ci        RecursStatistics(std::static_pointer_cast<ComponentTree>(child));
62a69a01cdSopenharmony_ci    }
63a69a01cdSopenharmony_ci    // layer pointer move to previous
64a69a01cdSopenharmony_ci    layer--;
65a69a01cdSopenharmony_ci}
66a69a01cdSopenharmony_ci}  // namespace
67a69a01cdSopenharmony_ci
68a69a01cdSopenharmony_ci/**
69a69a01cdSopenharmony_ci * @brief Page Node Id specification format
70a69a01cdSopenharmony_ci * @details
71a69a01cdSopenharmony_ci * |----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|----|
72a69a01cdSopenharmony_ci * |ALL COUNT -14   |NODECOUNT-14|BRHCNT -8|TRH |TWO WIDTH -14   |LAST WIDTH -14   |
73a69a01cdSopenharmony_ci */
74a69a01cdSopenharmony_cibool PageTree::SetNodeId()
75a69a01cdSopenharmony_ci{
76a69a01cdSopenharmony_ci    nodeId_ = 0;
77a69a01cdSopenharmony_ci    auto componentTree = TreeManager::GetInstance()->GetNewComponents();
78a69a01cdSopenharmony_ci    if (componentTree->GetNodeId() == 0) {
79a69a01cdSopenharmony_ci        WARN_LOG("Component Tree is Empty");
80a69a01cdSopenharmony_ci        return false;
81a69a01cdSopenharmony_ci    }
82a69a01cdSopenharmony_ci    if (componentTree->GetParent() != nullptr) {
83a69a01cdSopenharmony_ci        WARN_LOG("Component Tree is not root");
84a69a01cdSopenharmony_ci        return false;
85a69a01cdSopenharmony_ci    }
86a69a01cdSopenharmony_ci
87a69a01cdSopenharmony_ci    // init statistics variables
88a69a01cdSopenharmony_ci    pageCount = 0;
89a69a01cdSopenharmony_ci    nodeCount = 0;
90a69a01cdSopenharmony_ci    branchCount = 0;
91a69a01cdSopenharmony_ci    height = 1;
92a69a01cdSopenharmony_ci    layer = 0;
93a69a01cdSopenharmony_ci    lastWidth = 0;
94a69a01cdSopenharmony_ci    g_isLeftBranch = true;
95a69a01cdSopenharmony_ci
96a69a01cdSopenharmony_ci    // recurs statistics
97a69a01cdSopenharmony_ci    RecursStatistics(componentTree);
98a69a01cdSopenharmony_ci
99a69a01cdSopenharmony_ci    uint32_t twoWidth = componentTree->GetChildren().size();
100a69a01cdSopenharmony_ci    DEBUG_LOG_STR("Page Count: (%d), Node: (%d), Branch: (%d), Height: (%d), Two Width: (%d), Last Width: (%d)",
101a69a01cdSopenharmony_ci                  (uint32_t)pageCount, (uint32_t)nodeCount, (uint32_t)branchCount, height, lastWidth, twoWidth);
102a69a01cdSopenharmony_ci    count_ = (uint32_t)pageCount;
103a69a01cdSopenharmony_ci
104a69a01cdSopenharmony_ci    // make node id for compare page.
105a69a01cdSopenharmony_ci    nodeId_ |= pageCount << PAGE_COUNT_POSION;
106a69a01cdSopenharmony_ci    nodeId_ |= nodeCount << PAGE_NODE_COUNT_POSION;
107a69a01cdSopenharmony_ci    nodeId_ |= branchCount << PAGE_BRANCH_COUNT_POSION;
108a69a01cdSopenharmony_ci    nodeId_ |= height << PAGE_HEIGHT_POSION;
109a69a01cdSopenharmony_ci    nodeId_ |= twoWidth << PAGE_TWO_LAYER_WIDTH_POSION;
110a69a01cdSopenharmony_ci    nodeId_ |= lastWidth << PAGE_LAST_LAYER_WIDTH_POSION;
111a69a01cdSopenharmony_ci    TRACK_LOG_STR("Page Node ID: (0x%016llX)", nodeId_);
112a69a01cdSopenharmony_ci    // make node id for compare page.
113a69a01cdSopenharmony_ci    auto elementInfo = TreeManager::GetInstance()->GetNewElementInfoList((count_ - 1));
114a69a01cdSopenharmony_ci    if (elementInfo == nullptr) {
115a69a01cdSopenharmony_ci        ERROR_LOG("get new element info is nullptr");
116a69a01cdSopenharmony_ci        return false;
117a69a01cdSopenharmony_ci    }
118a69a01cdSopenharmony_ci    std::string pagePath = elementInfo->GetPagePath();
119a69a01cdSopenharmony_ci    TreeManager::GetInstance()->SetOldPagePath(pagePath);
120a69a01cdSopenharmony_ci    TRACK_LOG_STR("Componentpage path: (%s)", pagePath.c_str());
121a69a01cdSopenharmony_ci    return true;
122a69a01cdSopenharmony_ci}
123a69a01cdSopenharmony_ci}  // namespace WuKong
124a69a01cdSopenharmony_ci}  // namespace OHOS
125