174 lines
6.1 KiB
C#
174 lines
6.1 KiB
C#
/*
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
|
compliance with the License. You may obtain a copy of the License
|
|
at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
|
|
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
|
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
|
|
|
|
See the Apache Version 2.0 License for specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
using System.Diagnostics;
|
|
using Microsoft.Research.DryadLinq;
|
|
|
|
#pragma warning disable 1591
|
|
|
|
namespace Microsoft.Research.DryadLinq.Internal
|
|
{
|
|
/// <summary>
|
|
/// This class implements an object store that is used to store objects
|
|
/// needed for remote execution of DryadLINQ vertex code. All objects put
|
|
/// in the store must have the .NET Serializable attribute.
|
|
/// </summary>
|
|
/// <remarks>A DryadLINQ user should not need to use this class directly.</remarks>
|
|
/// <remarks>The methods in this class is not thread safe.</remarks>
|
|
public sealed class DryadLinqObjectStore
|
|
{
|
|
private const string ObjectStoreFileName = "DryadLinqObjectStore.bin";
|
|
|
|
internal static string GetClientSideObjectStorePath()
|
|
{
|
|
return DryadLinqCodeGen.GetPathForGeneratedFile(ObjectStoreFileName, null);
|
|
}
|
|
|
|
private static ArrayList s_objectList = null;
|
|
|
|
public static bool IsEmpty
|
|
{
|
|
get {
|
|
return (s_objectList == null || s_objectList.Count == 0);
|
|
}
|
|
}
|
|
|
|
public static void Clear()
|
|
{
|
|
s_objectList = null;
|
|
}
|
|
|
|
// this method is only used by the generated vertex code, and always
|
|
// assumes "DryadLinqObjectStore.bin" to be in the current directory
|
|
public static object Get(int idx)
|
|
{
|
|
if (s_objectList == null)
|
|
{
|
|
// Try to open the object store. First look in the parent directory
|
|
// (job directory when running normally), then try opening it from the path.
|
|
FileStream fs;
|
|
try
|
|
{
|
|
fs = new FileStream(Path.Combine(Directory.GetParent(Directory.GetCurrentDirectory()).FullName, ObjectStoreFileName), FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
}
|
|
catch (FileNotFoundException)
|
|
{
|
|
fs = new FileStream(ObjectStoreFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
}
|
|
|
|
BinaryFormatter bfm = new BinaryFormatter();
|
|
try
|
|
{
|
|
s_objectList = (ArrayList)bfm.Deserialize(fs);
|
|
}
|
|
catch (SerializationException e)
|
|
{
|
|
throw new DryadLinqException(DryadLinqErrorCode.FailedToDeserialize,
|
|
SR.FailedToDeserialize, e);
|
|
}
|
|
finally
|
|
{
|
|
if (fs != null) fs.Close();
|
|
}
|
|
}
|
|
|
|
if (idx >= s_objectList.Count)
|
|
{
|
|
throw new DryadLinqException(DryadLinqErrorCode.IndexOutOfRange,
|
|
SR.IndexOutOfRange);
|
|
}
|
|
return s_objectList[idx];
|
|
}
|
|
|
|
public static int Put(object obj)
|
|
{
|
|
if (s_objectList != null)
|
|
{
|
|
for (int idx = 0; idx < s_objectList.Count; idx++)
|
|
{
|
|
if (Object.ReferenceEquals(obj, s_objectList[idx]))
|
|
{
|
|
return idx;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (s_objectList == null)
|
|
{
|
|
s_objectList = new ArrayList(4);
|
|
}
|
|
s_objectList.Add(obj);
|
|
return (s_objectList.Count - 1);
|
|
}
|
|
|
|
// This method is only used by the client process to save the object store before submitting a job
|
|
// Like other generated files we need to save this file in the temp directory
|
|
public static void Save()
|
|
{
|
|
if (IsEmpty) return;
|
|
string objectStorePath = GetClientSideObjectStorePath();
|
|
|
|
FileStream fs = new FileStream(objectStorePath, FileMode.Create);
|
|
try
|
|
{
|
|
BinaryFormatter bfm = new BinaryFormatter();
|
|
bfm.Serialize(fs, s_objectList);
|
|
}
|
|
catch (SerializationException e)
|
|
{
|
|
foreach (object obj in s_objectList)
|
|
{
|
|
Type badType = TypeSystem.GetNonserializable(obj);
|
|
if (badType != null)
|
|
{
|
|
if (badType.IsGenericType &&
|
|
badType.GetGenericTypeDefinition() == typeof(DryadLinqQuery<>))
|
|
{
|
|
throw new DryadLinqException(DryadLinqErrorCode.CannotSerializeDryadLinqQuery,
|
|
SR.CannotSerializeDryadLinqQuery);
|
|
}
|
|
else
|
|
{
|
|
throw new DryadLinqException(DryadLinqErrorCode.CannotSerializeObject,
|
|
string.Format(SR.CannotSerializeObject, obj));
|
|
}
|
|
}
|
|
}
|
|
|
|
throw new DryadLinqException(DryadLinqErrorCode.GeneralSerializeFailure,
|
|
SR.GeneralSerializeFailure, e);
|
|
}
|
|
finally
|
|
{
|
|
if (fs != null) fs.Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|