Use JSON instead of pickle

Use JSON as it is shown to be much faster than pickle.
Also clean up the loading and saving functions.

Change-Id: I45b3dee7b4d59a1c0e0d38d4a83b543ac5839390
This commit is contained in:
Anthony King 2014-05-06 15:57:48 +01:00
parent 2cd1f0452e
commit 85b24acd6a
2 changed files with 43 additions and 58 deletions

View File

@ -15,8 +15,8 @@
from __future__ import print_function from __future__ import print_function
import json
import os import os
import pickle
import re import re
import subprocess import subprocess
import sys import sys
@ -80,7 +80,7 @@ class GitConfig(object):
return cls(configfile = os.path.join(gitdir, 'config'), return cls(configfile = os.path.join(gitdir, 'config'),
defaults = defaults) defaults = defaults)
def __init__(self, configfile, defaults=None, pickleFile=None): def __init__(self, configfile, defaults=None, jsonFile=None):
self.file = configfile self.file = configfile
self.defaults = defaults self.defaults = defaults
self._cache_dict = None self._cache_dict = None
@ -88,12 +88,11 @@ class GitConfig(object):
self._remotes = {} self._remotes = {}
self._branches = {} self._branches = {}
if pickleFile is None: self._json = jsonFile
self._pickle = os.path.join( if self._json is None:
self._json = os.path.join(
os.path.dirname(self.file), os.path.dirname(self.file),
'.repopickle_' + os.path.basename(self.file)) '.repo_' + os.path.basename(self.file) + '.json')
else:
self._pickle = pickleFile
def Has(self, name, include_defaults = True): def Has(self, name, include_defaults = True):
"""Return true if this configuration file has the key. """Return true if this configuration file has the key.
@ -248,50 +247,41 @@ class GitConfig(object):
return self._cache_dict return self._cache_dict
def _Read(self): def _Read(self):
d = self._ReadPickle() d = self._ReadJson()
if d is None: if d is None:
d = self._ReadGit() d = self._ReadGit()
self._SavePickle(d) self._SaveJson(d)
return d return d
def _ReadPickle(self): def _ReadJson(self):
try: try:
if os.path.getmtime(self._pickle) \ if os.path.getmtime(self._json) \
<= os.path.getmtime(self.file): <= os.path.getmtime(self.file):
os.remove(self._pickle) os.remove(self._json)
return None return None
except OSError: except OSError:
return None return None
try: try:
Trace(': unpickle %s', self.file) Trace(': parsing %s', self.file)
fd = open(self._pickle, 'rb') fd = open(self._json)
try: try:
return pickle.load(fd) return json.load(fd)
finally: finally:
fd.close() fd.close()
except EOFError: except (IOError, ValueError):
os.remove(self._pickle) os.remove(self._json)
return None
except IOError:
os.remove(self._pickle)
return None
except pickle.PickleError:
os.remove(self._pickle)
return None return None
def _SavePickle(self, cache): def _SaveJson(self, cache):
try: try:
fd = open(self._pickle, 'wb') fd = open(self._json, 'w')
try: try:
pickle.dump(cache, fd, pickle.HIGHEST_PROTOCOL) json.dump(cache, fd, indent=2)
finally: finally:
fd.close() fd.close()
except IOError: except (IOError, TypeError):
if os.path.exists(self._pickle): if os.path.exists(self.json):
os.remove(self._pickle) os.remove(self._json)
except pickle.PickleError:
if os.path.exists(self._pickle):
os.remove(self._pickle)
def _ReadGit(self): def _ReadGit(self):
""" """

View File

@ -14,10 +14,10 @@
# limitations under the License. # limitations under the License.
from __future__ import print_function from __future__ import print_function
import json
import netrc import netrc
from optparse import SUPPRESS_HELP from optparse import SUPPRESS_HELP
import os import os
import pickle
import re import re
import shutil import shutil
import socket import socket
@ -760,7 +760,7 @@ class _FetchTimes(object):
_ALPHA = 0.5 _ALPHA = 0.5
def __init__(self, manifest): def __init__(self, manifest):
self._path = os.path.join(manifest.repodir, '.repopickle_fetchtimes') self._path = os.path.join(manifest.repodir, '.repo_fetchtimes.json')
self._times = None self._times = None
self._seen = set() self._seen = set()
@ -779,22 +779,17 @@ class _FetchTimes(object):
def _Load(self): def _Load(self):
if self._times is None: if self._times is None:
try: try:
f = open(self._path, 'rb') f = open(self._path)
except IOError:
self._times = {}
return self._times
try:
try: try:
self._times = pickle.load(f) self._times = json.load(f)
except IOError: finally:
try: f.close()
os.remove(self._path) except (IOError, ValueError):
except OSError: try:
pass os.remove(self._path)
self._times = {} except OSError:
finally: pass
f.close() self._times = {}
return self._times
def Save(self): def Save(self):
if self._times is None: if self._times is None:
@ -808,13 +803,13 @@ class _FetchTimes(object):
del self._times[name] del self._times[name]
try: try:
f = open(self._path, 'wb') f = open(self._path, 'w')
try: try:
pickle.dump(self._times, f) json.dump(self._times, f, indent=2)
except (IOError, OSError, pickle.PickleError): finally:
try: f.close()
os.remove(self._path) except (IOError, TypeError):
except OSError: try:
pass os.remove(self._path)
finally: except OSError:
f.close() pass