172 lines
5.9 KiB
C#
172 lines
5.9 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.
|
||
|
||
*/
|
||
|
||
//
|
||
// <20> Microsoft Corporation. All rights reserved.
|
||
//
|
||
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;
|
||
|
||
namespace Microsoft.Research.DryadLinq.Internal
|
||
{
|
||
// This class implements an object store that is used to store objects
|
||
// needed for remote execution of managed vertex code. All objects put
|
||
// in the store must have the .NET Serializable attribute.
|
||
// Note: this class is not thread safe
|
||
public sealed class HpcLinqObjectStore
|
||
{
|
||
private const string ObjectStoreFileName = "HpcLinqObjectStore.bin";
|
||
|
||
internal static string GetClientSideObjectStorePath()
|
||
{
|
||
return HpcLinqCodeGen.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 "HpcLinqObjectStore.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(HpcLinqErrorCode.FailedToDeserialize,
|
||
SR.FailedToDeserialize, e);
|
||
}
|
||
finally
|
||
{
|
||
if (fs != null) fs.Close();
|
||
}
|
||
}
|
||
|
||
if (idx >= s_objectList.Count)
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.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);
|
||
BinaryFormatter bfm = new BinaryFormatter();
|
||
try
|
||
{
|
||
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(HpcLinqErrorCode.CannotSerializeHpcLinqQuery,
|
||
SR.CannotSerializeHpcLinqQuery);
|
||
}
|
||
else
|
||
{
|
||
throw new DryadLinqException(HpcLinqErrorCode.CannotSerializeObject,
|
||
string.Format(SR.CannotSerializeObject, obj));
|
||
}
|
||
}
|
||
}
|
||
|
||
throw new DryadLinqException(HpcLinqErrorCode.GeneralSerializeFailure,
|
||
SR.GeneralSerializeFailure, e);
|
||
}
|
||
finally
|
||
{
|
||
if (fs != null) fs.Close();
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|