trappy/caching: Couple of fixes

- json params loading represents keys as unicode, use dumps to fix it
- finalize_objects need to be run always for cases where some events not
  cached, fix it by moving it up and also handle bjackman's concern that we run
  it twice by skipping finalize for cached events.
- fix time normalization breakage as a result of the above changes

Change-Id: I2011de0ae8112e937ee61baee8d53a63d0bbe85a
Signed-off-by: Joel Fernandes <joelaf@google.com>
diff --git a/trappy/bare_trace.py b/trappy/bare_trace.py
index e4fec48..a953a60 100644
--- a/trappy/bare_trace.py
+++ b/trappy/bare_trace.py
@@ -134,6 +134,9 @@
 
     def finalize_objects(self):
         for trace_class in self.trace_classes:
+            # If cached, don't need to do any other DF operation
+            if trace_class.cached:
+                continue
             trace_class.tracer = self
             trace_class.create_dataframe()
             trace_class.finalize_object()
diff --git a/trappy/ftrace.py b/trappy/ftrace.py
index c0a40c2..226cd96 100644
--- a/trappy/ftrace.py
+++ b/trappy/ftrace.py
@@ -78,6 +78,7 @@
     def _check_trace_cache(self, params):
         cache_path = self._trace_cache_path()
         md5file = os.path.join(cache_path, 'md5sum')
+        basetime_path = os.path.join(cache_path, 'basetime')
         params_path = os.path.join(cache_path, 'params.json')
 
         for path in [cache_path, md5file, params_path]:
@@ -86,10 +87,15 @@
 
         with open(md5file) as f:
             cache_md5sum = f.read()
+        with open(basetime_path) as f:
+            self.basetime = float(f.read())
         with open(self.trace_path, 'rb') as f:
             trace_md5sum = hashlib.md5(f.read()).hexdigest()
         with open(params_path) as f:
-            cache_params = json.load(f)
+            cache_params = json.dumps(json.load(f))
+
+        # Convert to a json string for comparison
+        params = json.dumps(params)
 
         # check if cache is valid
         if cache_md5sum != trace_md5sum or cache_params != params:
@@ -100,6 +106,7 @@
     def _create_trace_cache(self, params):
         cache_path = self._trace_cache_path()
         md5file = os.path.join(cache_path, 'md5sum')
+        basetime_path = os.path.join(cache_path, 'basetime')
         params_path = os.path.join(cache_path, 'params.json')
 
         if os.path.exists(cache_path):
@@ -110,6 +117,9 @@
         with open(md5file, 'w') as f:
             f.write(md5sum)
 
+        with open(basetime_path, 'w') as f:
+            f.write(str(self.basetime))
+
         with open(params_path, 'w') as f:
             json.dump(params, f)
 
@@ -194,8 +204,15 @@
                     warnstr = "TRAPpy: Couldn't read {} from cache, reading it from trace".format(trace_class)
                     warnings.warn(warnstr)
 
+        if all([c.cached for c in self.trace_classes]):
+            if self.normalize_time:
+                self._normalize_time()
+            return
+
         self.__parse_trace_file(self.trace_path)
 
+        self.finalize_objects()
+
         if not self.__class__.disable_cache:
             try:
                 # Recreate basic cache directories only if nothing cached
@@ -212,8 +229,6 @@
                 warnings.warn(
                     "TRAPpy: Cache not created due to OS error: {0}".format(err))
 
-        self.finalize_objects()
-
         if self.normalize_time:
             self._normalize_time()