[game-data-packager] 01/02: Avoid two-pass processing of groups files
Simon McVittie
smcv at debian.org
Mon Feb 22 23:38:45 UTC 2016
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch master
in repository game-data-packager.
commit d219ef08935214d6a0b956d325b7243adf31e8c5
Author: Simon McVittie <smcv at debian.org>
Date: Mon Feb 22 23:38:07 2016 +0000
Avoid two-pass processing of groups files
Since commit 2b5a38e0 this has been crashing with io.UnsupportedOperation
"underlying stream is not seekable" for some people and in some
situations, but not consistently. Duplicating the list of group names
at the beginning so that we can process the file linearly is not very
expensive, and should be mitigated by the compression anyway.
---
Makefile | 2 +-
game_data_packager/__init__.py | 26 ++++++++++----------------
tools/compile_yaml.py | 6 ++++++
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/Makefile b/Makefile
index 55d1001..a1bd516 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ out/%: data/%
@mkdir -p out
if [ -L $< ]; then cp -a $< $@ ; else install -m644 $< $@ ; fi
-out/vfs/%.json: data/%.yaml
+out/vfs/%.json: data/%.yaml tools/compile_yaml.py
@mkdir -p out/vfs
$(PYTHON) tools/compile_yaml.py $< $@
diff --git a/game_data_packager/__init__.py b/game_data_packager/__init__.py
index 7f1fab6..d110df9 100644
--- a/game_data_packager/__init__.py
+++ b/game_data_packager/__init__.py
@@ -945,31 +945,24 @@ class GameData(object):
current_group = None
attributes = {}
- # Before doing anything else, we do one pass through the list
- # of groups to record that each one is a group, so that when we
- # encounter an entry that is not known to be a group in a
- # group's members, it is definitely a file.
- stream.seek(0)
-
for line in stream:
stripped = line.strip()
- if stripped.startswith('['):
- assert stripped.endswith(']'), repr(stripped)
- self._ensure_group(stripped[1:-1])
-
- # Now go back and re-read them, with their members this time.
- stream.seek(0)
-
- for line in stream:
- stripped = line.strip()
if stripped == '' or stripped.startswith('#'):
continue
- if stripped.startswith('['):
+ # The group data starts with a list of groups. This is necessary
+ # so we can know whether a group member, encountered later on in
+ # the data, is a group or a file.
+ if stripped.startswith('*'):
+ assert current_group is None
+ self._ensure_group(stripped[1:])
+ # After that, [Group] opens a section for each group
+ elif stripped.startswith('['):
assert stripped.endswith(']'), repr(stripped)
current_group = self._ensure_group(stripped[1:-1])
attributes = {}
+ # JSON metadata is on a line with {}
elif stripped.startswith('{'):
assert current_group is not None
attributes = json.loads(stripped)
@@ -977,6 +970,7 @@ class GameData(object):
for k, v in attributes.items():
assert hasattr(current_group, k), k
setattr(current_group, k, v)
+ # Every other line is a member, either a file or a group
else:
f = self._add_hash(stripped, 'size_and_md5')
# f can either be a WantedFile or a FileGroup here
diff --git a/tools/compile_yaml.py b/tools/compile_yaml.py
index fd2056a..698fa7e 100755
--- a/tools/compile_yaml.py
+++ b/tools/compile_yaml.py
@@ -46,6 +46,12 @@ def main(f, out):
if groups is not None:
with open(offload + '.tmp', 'w', encoding='utf-8') as writer:
assert isinstance(groups, dict)
+ # The group data starts with a list of groups. This is necessary
+ # so we can know whether a group member, encountered later on in
+ # the data, is a group or a file.
+ for group_name in sorted(groups.keys()):
+ writer.write('*%s\n' % group_name)
+
for group_name, group_data in sorted(groups.items()):
writer.write('[%s]\n' % group_name)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/game-data-packager.git
More information about the Pkg-games-commits
mailing list