Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
FileVersionStorage.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.IO;
6 using System.Text;
7 using SiliconStudio.Core;
8 using SiliconStudio.Core.IO;
9 using SiliconStudio.Core.Serialization.Serializers;
10 using SiliconStudio.Core.Storage;
11 
12 namespace SiliconStudio.BuildEngine
13 {
14  /// <summary>
15  /// Storage used for <see cref="FileVersionKey"/> associated with an <see cref="ObjectId"/>.
16  /// </summary>
17  [DataSerializerGlobal(typeof(KeyValuePairSerializer<FileVersionKey, ObjectId>))]
18  public sealed class FileVersionStorage : DictionaryStore<FileVersionKey, ObjectId>
19  {
20  /// <summary>
21  /// Initializes a new instance of the <see cref="FileVersionStorage"/> class.
22  /// </summary>
23  /// <param name="stream">The localStream.</param>
24  public FileVersionStorage(Stream stream) : base(stream)
25  {
26  }
27 
28  /// <summary>
29  /// Compacts the specified storage path.
30  /// </summary>
31  /// <param name="storagePath">The storage path.</param>
32  /// <returns><c>true</c> if the storage path was successfully compacted, <c>false</c> otherwise.</returns>
33  public static bool Compact(string storagePath)
34  {
35  FileStream fileStreamExclusive;
36  try
37  {
38  fileStreamExclusive = new FileStream(storagePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
39  }
40  catch (Exception)
41  {
42  return false;
43  }
44 
45  try
46  {
47  using (var localTracker = new FileVersionStorage(fileStreamExclusive) { UseTransaction = true, AutoLoadNewValues = false })
48  {
49  localTracker.LoadNewValues();
50  var latestVersion = new Dictionary<string, KeyValuePair<FileVersionKey, ObjectId>>(StringComparer.OrdinalIgnoreCase);
51  foreach (var keyValue in localTracker.GetValues())
52  {
53  var filePath = keyValue.Key.Path;
54  KeyValuePair<FileVersionKey, ObjectId> previousKeyValue;
55  if (!latestVersion.TryGetValue(filePath, out previousKeyValue) || keyValue.Key.LastModifiedDate > previousKeyValue.Key.LastModifiedDate)
56  {
57  latestVersion[filePath] = keyValue;
58  }
59  }
60  localTracker.Reset();
61  localTracker.AddValues(latestVersion.Values);
62  localTracker.Save();
63  }
64  }
65  catch (Exception)
66  {
67  return false;
68 
69  }
70  return true;
71  }
72 
73  protected override List<KeyValuePair<FileVersionKey, ObjectId>> ReadEntries(System.IO.Stream localStream)
74  {
75  // As the FileVersionStorage is not used at runtime but only at build time, it is not currently optimized
76  // TODO: performance of encoding/decoding could be improved using some manual (but much more laborious) code.
77  var reader = new StreamReader(localStream, Encoding.UTF8);
78  string line;
79  var entries = new List<KeyValuePair<FileVersionKey, ObjectId>>();
80  while ((line = reader.ReadLine()) != null)
81  {
82  var values = line.Split('\t');
83  if (values.Length != 4)
84  {
85  continue;
86  }
87  // Path: values[0]
88  var key = new FileVersionKey() { Path = values[0]};
89 
90  long dateTime;
91  if (!long.TryParse(values[1], out dateTime))
92  {
93  throw new InvalidOperationException("Unable to decode datetime [{0}] when reading file version index".ToFormat(values[1]));
94  }
95  key.LastModifiedDate = new DateTime(dateTime);
96 
97  if (!long.TryParse(values[2], out key.FileSize))
98  {
99  throw new InvalidOperationException("Unable to decode filesize [{0}] when reading file version index".ToFormat(values[2]));
100  }
101  var objectIdStr = values[3];
102 
103  ObjectId objectId;
104  if (!ObjectId.TryParse(objectIdStr, out objectId))
105  {
106  throw new InvalidOperationException("Unable to decode objectid [{0}] when reading file version index".ToFormat(objectIdStr));
107  }
108 
109  var entry = new KeyValuePair<FileVersionKey, ObjectId>(key, objectId);
110  entries.Add(entry);
111  }
112  return entries;
113  }
114 
115  protected override void WriteEntry(Stream localStream, KeyValuePair<FileVersionKey, ObjectId> value)
116  {
117  var key = value.Key;
118  var line = string.Format("{0}\t{1}\t{2}\t{3}\n", key.Path, key.LastModifiedDate.Ticks, key.FileSize, value.Value);
119  var bytes = Encoding.UTF8.GetBytes(line);
120  localStream.Write(bytes, 0, bytes.Length);
121  }
122  }
123 }
Storage used for FileVersionKey associated with an ObjectId.
FileVersionStorage(Stream stream)
Initializes a new instance of the FileVersionStorage class.
System.Text.Encoding Encoding
System.IO.FileMode FileMode
Definition: ScriptSync.cs:33
override void WriteEntry(Stream localStream, KeyValuePair< FileVersionKey, ObjectId > value)
A hash to uniquely identify data.
Definition: ObjectId.cs:13
static bool Compact(string storagePath)
Compacts the specified storage path.
override List< KeyValuePair< FileVersionKey, ObjectId > > ReadEntries(System.IO.Stream localStream)
static bool TryParse(string input, out ObjectId result)
Tries to parse an ObjectId from a string.
Definition: ObjectId.cs:102