aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
diff options
context:
space:
mode:
authorJustin Clarke Casey2009-03-06 20:12:08 +0000
committerJustin Clarke Casey2009-03-06 20:12:08 +0000
commit85774de2310141f4311bc3df1946d44df9ddde59 (patch)
treee86febe5873121d9a529f6d77a2a7ee929030425 /OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
parent* Protects RestClient from crashing with dictionary exception, which leads to... (diff)
downloadopensim-SC_OLD-85774de2310141f4311bc3df1946d44df9ddde59.zip
opensim-SC_OLD-85774de2310141f4311bc3df1946d44df9ddde59.tar.gz
opensim-SC_OLD-85774de2310141f4311bc3df1946d44df9ddde59.tar.bz2
opensim-SC_OLD-85774de2310141f4311bc3df1946d44df9ddde59.tar.xz
* Improve memory usage when writing OARs
* This should make saving large OARs a somewhat better experience * However, the problem where saving an archive pulls large numbers of assets into the asset cache isn't yet resolved * This patch also removes lots of archive writing spam that crept in
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs98
1 files changed, 44 insertions, 54 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
index 09ea7ec..506fcc5 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/TarArchiveWriter.cs
@@ -39,65 +39,80 @@ namespace OpenSim.Region.CoreModules.World.Archiver
39 { 39 {
40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 41
42 protected Dictionary<string, byte[]> m_files = new Dictionary<string, byte[]>();
43
44 protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); 42 protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
45 43
46 /// <summary> 44 /// <summary>
47 /// Add a directory to the tar archive. We can only handle one path level right now! 45 /// Binary writer for the underlying stream
46 /// </summary>
47 protected BinaryWriter m_bw;
48
49 public TarArchiveWriter(Stream s)
50 {
51 m_bw = new BinaryWriter(s);
52 }
53
54 /// <summary>
55 /// Write a directory entry to the tar archive. We can only handle one path level right now!
48 /// </summary> 56 /// </summary>
49 /// <param name="dirName"></param> 57 /// <param name="dirName"></param>
50 public void AddDir(string dirName) 58 public void WriteDir(string dirName)
51 { 59 {
52 // Directories are signalled by a final / 60 // Directories are signalled by a final /
53 if (!dirName.EndsWith("/")) 61 if (!dirName.EndsWith("/"))
54 dirName += "/"; 62 dirName += "/";
55 63
56 AddFile(dirName, new byte[0]); 64 WriteFile(dirName, new byte[0]);
57 } 65 }
58 66
59 /// <summary> 67 /// <summary>
60 /// Add a file to the tar archive 68 /// Write a file to the tar archive
61 /// </summary> 69 /// </summary>
62 /// <param name="filePath"></param> 70 /// <param name="filePath"></param>
63 /// <param name="data"></param> 71 /// <param name="data"></param>
64 public void AddFile(string filePath, string data) 72 public void WriteFile(string filePath, string data)
65 { 73 {
66 AddFile(filePath, m_asciiEncoding.GetBytes(data)); 74 WriteFile(filePath, m_asciiEncoding.GetBytes(data));
67 } 75 }
68 76
69 /// <summary> 77 /// <summary>
70 /// Add a file to the tar archive 78 /// Write a file to the tar archive
71 /// </summary> 79 /// </summary>
72 /// <param name="filePath"></param> 80 /// <param name="filePath"></param>
73 /// <param name="data"></param> 81 /// <param name="data"></param>
74 public void AddFile(string filePath, byte[] data) 82 public void WriteFile(string filePath, byte[] data)
75 { 83 {
76 m_files[filePath] = data; 84 if (filePath.Length > 100)
85 WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
86
87 char fileType;
88
89 if (filePath.EndsWith("/"))
90 {
91 fileType = '5';
92 }
93 else
94 {
95 fileType = '0';
96 }
97
98 WriteEntry(filePath, data, fileType);
77 } 99 }
78 100
79 /// <summary> 101 /// <summary>
80 /// Write the raw tar archive data to a stream. The stream will be closed on completion. 102 /// Finish writing the raw tar archive data to a stream. The stream will be closed on completion.
81 /// </summary> 103 /// </summary>
82 /// <param name="s">Stream to which to write the data</param> 104 /// <param name="s">Stream to which to write the data</param>
83 /// <returns></returns> 105 /// <returns></returns>
84 public void WriteTar(Stream s) 106 public void Close()
85 { 107 {
86 BinaryWriter bw = new BinaryWriter(s);
87
88 foreach (string filePath in m_files.Keys)
89 {
90 WriteFile(bw, filePath, m_files[filePath]);
91 }
92
93 //m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks"); 108 //m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks");
94 109
95 // Write two consecutive 0 blocks to end the archive 110 // Write two consecutive 0 blocks to end the archive
96 byte[] finalZeroPadding = new byte[1024]; 111 byte[] finalZeroPadding = new byte[1024];
97 bw.Write(finalZeroPadding); 112 m_bw.Write(finalZeroPadding);
98 113
99 bw.Flush(); 114 m_bw.Flush();
100 bw.Close(); 115 m_bw.Close();
101 } 116 }
102 117
103 public static byte[] ConvertDecimalToPaddedOctalBytes(int d, int padding) 118 public static byte[] ConvertDecimalToPaddedOctalBytes(int d, int padding)
@@ -119,39 +134,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
119 134
120 return oBytes; 135 return oBytes;
121 } 136 }
122
123 /// <summary>
124 /// Write a particular file of data
125 /// </summary>
126 /// <param name="filePath"></param>
127 /// <param name="data"></param>
128 protected void WriteFile(BinaryWriter bw, string filePath, byte[] data)
129 {
130 if (filePath.Length > 100)
131 WriteEntry(bw, "././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
132
133 char fileType;
134
135 if (filePath.EndsWith("/"))
136 {
137 fileType = '5';
138 }
139 else
140 {
141 fileType = '0';
142 }
143
144 WriteEntry(bw, filePath, data, fileType);
145 }
146 137
147 /// <summary> 138 /// <summary>
148 /// Write a particular file of data 139 /// Write a particular entry
149 /// </summary> 140 /// </summary>
150 /// <param name="bw"></param>
151 /// <param name="filePath"></param> 141 /// <param name="filePath"></param>
152 /// <param name="data"></param> 142 /// <param name="data"></param>
153 /// <param name="fileType"></param> 143 /// <param name="fileType"></param>
154 protected void WriteEntry(BinaryWriter bw, string filePath, byte[] data, char fileType) 144 protected void WriteEntry(string filePath, byte[] data, char fileType)
155 { 145 {
156 byte[] header = new byte[512]; 146 byte[] header = new byte[512];
157 147
@@ -208,10 +198,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
208 header[154] = 0; 198 header[154] = 0;
209 199
210 // Write out header 200 // Write out header
211 bw.Write(header); 201 m_bw.Write(header);
212 202
213 // Write out data 203 // Write out data
214 bw.Write(data); 204 m_bw.Write(data);
215 205
216 if (data.Length % 512 != 0) 206 if (data.Length % 512 != 0)
217 { 207 {
@@ -220,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
220 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired); 210 //m_log.DebugFormat("[TAR ARCHIVE WRITER]: Padding data with {0} bytes", paddingRequired);
221 211
222 byte[] padding = new byte[paddingRequired]; 212 byte[] padding = new byte[paddingRequired];
223 bw.Write(padding); 213 m_bw.Write(padding);
224 } 214 }
225 } 215 }
226 } 216 }