summaryrefslogtreecommitdiff
path: root/startop/scripts/iorap/lib/inode2filename.py
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2020-08-31 21:21:38 -0700
committerXin Li <delphij@google.com>2020-08-31 21:21:38 -0700
commit628590d7ec80e10a3fc24b1c18a1afb55cca10a8 (patch)
tree4b1c3f52d86d7fb53afbe9e9438468588fa489f8 /startop/scripts/iorap/lib/inode2filename.py
parentb11b8ec3aec8bb42f2c07e1c5ac7942da293baa8 (diff)
parentd2d3a20624d968199353ccf6ddbae6f3ac39c9af (diff)
Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)
Bug: 166295507 Merged-In: I3d92a6de21a938f6b352ec26dc23420c0fe02b27 Change-Id: Ifdb80563ef042738778ebb8a7581a97c4e3d96e2
Diffstat (limited to 'startop/scripts/iorap/lib/inode2filename.py')
-rw-r--r--startop/scripts/iorap/lib/inode2filename.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/startop/scripts/iorap/lib/inode2filename.py b/startop/scripts/iorap/lib/inode2filename.py
new file mode 100644
index 000000000000..2e713936319a
--- /dev/null
+++ b/startop/scripts/iorap/lib/inode2filename.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union, TextIO
+
+import re
+
+class Inode2Filename:
+ """
+ Parses a text file of the format
+ "uint(dev_t) uint(ino_t) int(file_size) string(filepath)\\n"*
+
+ Lines not matching this format are ignored.
+ """
+
+ def __init__(self, inode_data_file: TextIO):
+ """
+ Create an Inode2Filename that reads cached inode from a file saved earlier
+ (e.g. with pagecache.py -d or with inode2filename --format=textcache)
+
+ :param inode_data_file: a file object (e.g. created with open or StringIO).
+
+ Lifetime: inode_data_file is only used during the construction of the object.
+ """
+ self._inode_table = Inode2Filename.build_inode_lookup_table(inode_data_file)
+
+ @classmethod
+ def new_from_filename(cls, textcache_filename: str) -> 'Inode2Filename':
+ """
+ Create an Inode2Filename that reads cached inode from a file saved earlier
+ (e.g. with pagecache.py -d or with inode2filename --format=textcache)
+
+ :param textcache_filename: path to textcache
+ """
+ with open(textcache_filename) as inode_data_file:
+ return cls(inode_data_file)
+
+ @staticmethod
+ def build_inode_lookup_table(inode_data_file: TextIO) -> Dict[Tuple[int, int], Tuple[str, str]]:
+ """
+ :return: map { (device_int, inode_int) -> (filename_str, size_str) }
+ """
+ inode2filename = {}
+ for line in inode_data_file:
+ # stat -c "%d %i %s %n
+ # device number, inode number, total size in bytes, file name
+ result = re.match('([0-9]+)d? ([0-9]+) -?([0-9]+) (.*)', line)
+ if result:
+ inode2filename[(int(result.group(1)), int(result.group(2)))] = \
+ (result.group(4), result.group(3))
+
+ return inode2filename
+
+ def resolve(self, dev_t: int, ino_t: int) -> Optional[str]:
+ """
+ Return a filename (str) from a (dev_t, ino_t) inode pair.
+
+ Returns None if the lookup fails.
+ """
+ maybe_result = self._inode_table.get((dev_t, ino_t))
+
+ if not maybe_result:
+ return None
+
+ return maybe_result[0] # filename str
+
+ def __len__(self) -> int:
+ """
+ :return: the number of inode entries parsed from the file.
+ """
+ return len(self._inode_table)
+
+ def __repr__(self) -> str:
+ """
+ :return: string representation for debugging/test failures.
+ """
+ return "Inode2Filename%s" %(repr(self._inode_table))
+
+ # end of class.