Implement persistent caching for simplify_condition
Store the results of simplify_condition in a json cache file, next to the pro2cmake.py script. Dramatically speeds up re-conversion of projects. The cache is cleared whenever the content of the condition_simplifier.py file changes, effectively presuming that the condition computing code has changed. Sample times. Initial corelib.pro conversion - 142.13 seconds. Next re-conversion with hot cache - 1.17 seconds. Change-Id: I8790b2736358236e4b23bcb5f10f45a36fdfa426 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Qt CMake Build Bot
This commit is contained in:
parent
590213e531
commit
f23b7e1476
@ -29,8 +29,8 @@
|
||||
|
||||
|
||||
import re
|
||||
|
||||
from sympy import simplify_logic, And, Or, Not, SympifyError
|
||||
from condition_simplifier_cache import simplify_condition_memoize
|
||||
|
||||
|
||||
def _iterate_expr_tree(expr, op, matches):
|
||||
@ -160,6 +160,7 @@ def _recursive_simplify(expr):
|
||||
return expr
|
||||
|
||||
|
||||
@simplify_condition_memoize
|
||||
def simplify_condition(condition: str) -> str:
|
||||
input_condition = condition.strip()
|
||||
|
||||
|
113
util/cmake/condition_simplifier_cache.py
Normal file
113
util/cmake/condition_simplifier_cache.py
Normal file
@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
#############################################################################
|
||||
##
|
||||
## Copyright (C) 2018 The Qt Company Ltd.
|
||||
## Contact: https://www.qt.io/licensing/
|
||||
##
|
||||
## This file is part of the plugins of the Qt Toolkit.
|
||||
##
|
||||
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
## Commercial License Usage
|
||||
## Licensees holding valid commercial Qt licenses may use this file in
|
||||
## accordance with the commercial license agreement provided with the
|
||||
## Software or, alternatively, in accordance with the terms contained in
|
||||
## a written agreement between you and The Qt Company. For licensing terms
|
||||
## and conditions see https://www.qt.io/terms-conditions. For further
|
||||
## information use the contact form at https://www.qt.io/contact-us.
|
||||
##
|
||||
## GNU General Public License Usage
|
||||
## Alternatively, this file may be used under the terms of the GNU
|
||||
## General Public License version 3 as published by the Free Software
|
||||
## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
## included in the packaging of this file. Please review the following
|
||||
## information to ensure the GNU General Public License requirements will
|
||||
## be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
##
|
||||
## $QT_END_LICENSE$
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
|
||||
import atexit
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from typing import Callable
|
||||
|
||||
|
||||
def get_current_file_path() -> str:
|
||||
try:
|
||||
this_file = __file__
|
||||
except NameError:
|
||||
this_file = sys.argv[0]
|
||||
this_file = os.path.abspath(this_file)
|
||||
return this_file
|
||||
|
||||
|
||||
def get_cache_location() -> str:
|
||||
this_file = get_current_file_path()
|
||||
dir_path = os.path.dirname(this_file)
|
||||
cache_path = os.path.join(dir_path, ".pro2cmake_cache", "cache.json")
|
||||
return cache_path
|
||||
|
||||
|
||||
def get_file_checksum(file_path: str) -> str:
|
||||
try:
|
||||
with open(file_path, "r") as content_file:
|
||||
content = content_file.read()
|
||||
except IOError:
|
||||
content = time.time()
|
||||
checksum = hashlib.md5(content.encode("utf-8")).hexdigest()
|
||||
return checksum
|
||||
|
||||
|
||||
def get_condition_simplifier_checksum() -> str:
|
||||
current_file_path = get_current_file_path()
|
||||
dir_name = os.path.dirname(current_file_path)
|
||||
condition_simplifier_path = os.path.join(dir_name, "condition_simplifier.py")
|
||||
return get_file_checksum(condition_simplifier_path)
|
||||
|
||||
|
||||
def init_cache_dict():
|
||||
return {
|
||||
"checksum": get_condition_simplifier_checksum(),
|
||||
"schema_version": "1",
|
||||
"cache": {"conditions": {}},
|
||||
}
|
||||
|
||||
|
||||
def simplify_condition_memoize(f: Callable[[str], str]):
|
||||
cache_path = get_cache_location()
|
||||
cache_file_content = None
|
||||
|
||||
if os.path.exists(cache_path):
|
||||
try:
|
||||
with open(cache_path, "r") as cache_file:
|
||||
cache_file_content = json.load(cache_file)
|
||||
except (IOError, ValueError):
|
||||
pass
|
||||
|
||||
if not cache_file_content:
|
||||
cache_file_content = init_cache_dict()
|
||||
|
||||
current_checksum = get_condition_simplifier_checksum()
|
||||
if cache_file_content["checksum"] != current_checksum:
|
||||
cache_file_content = init_cache_dict()
|
||||
|
||||
def update_cache_file():
|
||||
if not os.path.exists(cache_path):
|
||||
os.makedirs(os.path.dirname(cache_path), exist_ok=True)
|
||||
with open(cache_path, "w") as cache_file_write_handle:
|
||||
json.dump(cache_file_content, cache_file_write_handle, indent=4)
|
||||
|
||||
atexit.register(update_cache_file)
|
||||
|
||||
def helper(condition: str) -> str:
|
||||
if condition not in cache_file_content["cache"]["conditions"]:
|
||||
cache_file_content["cache"]["conditions"][condition] = f(condition)
|
||||
return cache_file_content["cache"]["conditions"][condition]
|
||||
|
||||
return helper
|
Loading…
x
Reference in New Issue
Block a user