diff --git a/tutorial/Cache.pike b/tutorial/Cache.pike
index 06459f3ee5cc95938f75d32798bad09bc47a9ede..5dec74c3cfaf12b45d513ee03ed93b33393984ce 100644
--- a/tutorial/Cache.pike
+++ b/tutorial/Cache.pike
@@ -1,34 +1,65 @@
 mapping data=([]);
 string file;
+Stdio.File log;
 
-int savers;
-
-mixed `[](string key)
+mixed `[](mixed key)
 {
   return data[key];
 }
 
 void save()
 {
-  Stdio.write_file(file,encode_value(data));
+  if(Stdio.write_file(file+".tmp",encode_value(data)))
+  {
+    if(mv(file+".tmp",file))
+    {
+      if(log) destruct(log);
+      rm(file+".log");
+    }
+  }
 }
 
-mixed `[]=(string key, mixed val)
+mixed `[]=(mixed key, mixed val)
 {
+  if(data[key] == val) return val;
   data[key]=val;
-  return class delaysave
-  {
-    void create() { savers++; }
-    void destroy() { if(!--savers) save(); }
-  }();
+
+  if(!log) log=Stdio.File(file+".log","wct");
+
+  log->write(
+    replace(encode_value( ({key,val}) ),"\0","\0\1")+"\0\0"
+    );
+    
+  return val;
 }
 
 void create(string f)
 {
+  werror("Cache: %s",f);
   file=f;
   catch {
     data=decode_value(Stdio.read_file(file));
+    werror(" %d entries",sizeof(data));
   };
+
+  catch {
+    if(string s=Stdio.read_file(file+".log"))
+    {
+      array t=s/"\0\0";
+      t=t[..sizeof(t)-2];
+      foreach(t, string tmp)
+	{
+	  string key,val;
+	  [key,val]=decode_value(replace(tmp,"\0\1","\0"));
+	  data[key]=val;
+	}
+      werror(" + %d logged",sizeof(t));
+      save();
+    }
+  };
+
+  werror("\n");
+
   atexit(save);
 }