Потенциальное использование для SoftReference со значением (равняется) равенству

Я ранее прихожу к выводу, что, если Вам нужен SoftReference со значением (равняется) базирующемуся равенству тогда, у каждого был плохой дизайн, за исключением interner от этого. Это следует за Google Collections и Guava не включая такой класс. Но я столкнулся с проблемой, что я думаю, мог использовать такой объект.

У нас есть система управления активами в системе средств визуализации визуальных эффектов с 100's процессов, выполняющих то же задание, которые только отличаются по числу кадра, которое оно представляет. У нас есть база данных Oracle, которая должна записать все используемые активы. Вместо того, чтобы загнать Oracle с идентичными вставками, где только один успешно выполнится от всех заданий в системе управления активами среднего уровня, мы можем использовать HashSet, чтобы записать, если объект, который был бы вставлен в Oracle.

Я мог использовать Google MapMaker с истечением, но я не хочу должным быть волноваться о получении корректного истечения, у нас есть рендеринг, который работает в течение многих часов и некоторых за дни. Используя SoftReference с равняется равенству, походит на намного лучший путь, таким образом, JVM справится со сборкой "мусора" автоматически.

Для других проблем, которые я хочу решить с ConcurrentHashMap со сборкой "мусора", я использовал бы сильную ссылку в HashMap, поскольку ключ для получения равняется () равенству и SoftReference как значение, таким образом, JVM может собрать "мусор" что-то, но в этом случае, значение не имеет значения, и у меня нет значения для обертывания в SoftReference для помещения там. Таким образом, кажется, что использование SoftReference с равняется (), добился бы цели.

Какие-либо другие предложения на этом?

9
задан Blair Zajac 12 February 2010 в 07:12
поделиться

3 ответа

В большинстве случаев, когда вы хотите использовать мягкие ссылки с Google Collections, вам следует вызвать

MapMaker.softValues()

. С сильными ключами, но мягкими значениями, поиск будет использовать равенство, а пары ключ-значение будут собираться мусором при нехватке памяти.

1
ответ дан 5 December 2019 в 02:07
поделиться

Мне удалось получить многоязычную поддержку через файлы ресурсов .NET, применив интересный взлом. Для каждого элемента управления Report существует неиспользуемое свойство, называемое, в свою очередь, StartLocId. С помощью этого свойства можно указать имя ресурса для каждого элемента управления. Идея здесь заключается в том, что вы будете закольцовывать определение отчета, ища элементы управления, которые имеют набор свойств, заданных для StartLocID. Если свойство установлено, замените Текст этого элемента управления на Текст ресурса, указанный в StartLocID. Таким образом, идея заключается в следующем:

  1. Загрузите файл RDLC в память, как XML-файл
  2. Выполните тегирование XML-файла с помощью XPath, ища свойства StartLocID
  3. Замените iniveText этого узла XML ресурсом, указанным в StartLocID
  4. Загрузите элемент управления EventViewer с помощью копии памяти

См. функцию ниже, которая будет выполнять именно то, что я упомянул выше.

Private Sub LocalizeReport()

    Dim xmlDoc As XmlDocument = New XmlDocument
    Dim asm As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
    'create in memory, a XML file from a embedded resource
    Dim xmlStream As Stream = asm.GetManifestResourceStream(ReportViewer1.LocalReport.ReportEmbeddedResource)

    Try
        'Load the RDLC file into a XML doc
        xmlDoc.Load(xmlStream)
    Catch e As Exception
        'HANDLE YOUR ERROR HERE
    End Try

    'Create an XmlNamespaceManager to resolve the default namespace
    Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(xmlDoc.NameTable)
    nsmgr.AddNamespace("nm", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition")
    nsmgr.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")

    'IMPORTANT LINE BELOW
    'YOU WILL NEED TO SET THIS TO YOUR RESOURCE MANAGER, OTHERWISE NOTHING WILL WORK
    Dim rm As ResourceManager = New ResourceManager("Insurance.Subs.WinUI.Controls.Resources", asm)

    'Loop through each node in the XML file, that has the ValueLOCId property set.
    'Using this property as a workaround for localization support.  The value specified in this
    'property will determine what resource to use for translation.
    Dim node As XmlNode
    For Each node In xmlDoc.DocumentElement.SelectNodes(String.Format("//nm:{0}[@rd:LocID]", "Value"), nsmgr)  'XPath to LocID
        Dim nodeValue As String = node.InnerText
        If (String.IsNullOrEmpty(nodeValue) Or Not nodeValue.StartsWith("=")) Then
            Try
                Dim localizedValue As String = node.Attributes("rd:LocID").Value

                'Get the resource via string
                localizedValue = rm.GetString(localizedValue)
                If Not String.IsNullOrEmpty(localizedValue) Then
                    'Set the text value - via the retrieved information from resource file
                    node.InnerText = localizedValue
                End If

            Catch ex As Exception
                'handle error
            End Try
        End If
    Next

    ReportViewer1.LocalReport.ReportPath = String.Empty
    ReportViewer1.LocalReport.ReportEmbeddedResource = Nothing
    'Load the updated RDLC document into LocalReport object.
    Dim rdlcOutputStream As StringReader = New StringReader(xmlDoc.DocumentElement.OuterXml)
    Using rdlcOutputStream
        ReportViewer1.LocalReport.LoadReportDefinition(rdlcOutputStream)
    End Using

End Sub
-121--3294757-

Следующий код должен выполнять эту функцию. Производительность будет зависеть от размера диапазона, подлежащего суммированию. Чем больше элементов, тем лучше он будет выполнять по сравнению с наивным добавлением подмножества в каждой итерации

 int getSum(int[] arr, int wanted)
        {
            var pre = new int[arr.Length];
            pre[0] = 0;
            pre[1] = arr[0];
            int max = 0;
            int skip = 1;
            for (var i = 1; i < arr.Length; i++)
            {
                skip--;
                //if the sum is marked invalid with a zero skip
                var current = arr[i];
                //calculate the index once
                int preIndex = i + 1;
                if (current == 0)
                {
                    skip = wanted;
                    pre[preIndex] = pre[i];
                    continue;
                }
                //store the sum of all elements until the current position
                pre[preIndex] = pre[i] + current;
                //find the lower end of the range under investigation now
                var lower = i - wanted;
                //if we haven't reached the wanted index yet we have no sum or if 
                //it's less than wanted element since we met a 0 
                //just go to the next element
                if (lower < 0 || skip > 0)
                    continue;
                var sum = pre[preIndex] - pre[lower];
                if (sum > max)
                    max = sum;
            }
            return max;
        }
-121--3950508-

Я думаю, что этот класс будет удовлетворять вашим потребностям:

import java.util.*;
import java.lang.ref.*;

public class SoftSet<T> extends AbstractSet<T> {

  private final WeakHashMap<T,SoftReference<T>> data = new WeakHashMap<T,SoftReference<T>>();

  public boolean add(T t) {
    return null == data.put(t, new SoftReference<T>(t));
  }

  public boolean remove(Object o) {
    return null != data.remove(o);
  }

  public boolean contains(Object o) {
    return data.containsKey(o);
  }

  public Iterator<T> iterator() {
    return data.keySet().iterator();
  }

  public int size() {
    return data.size();
  }

  public void clear() {
    data.clear();
  }

  public boolean removeAll(Collection<?> c) {
    return data.keySet().removeAll(c);
  }

  public boolean retainAll(Collection<?> c) {
    return data.keySet().retainAll(c);
  }
}

Способ, которым это должно работать, заключается в том, что как только мягкая ссылка, которая является значением, очищается, то значение становится слабо достижимым, и ключ может быть удален из внутренней карты.

0
ответ дан 5 December 2019 в 02:07
поделиться

Поскольку не существует ConcurrentHashSet с использованием мягких ссылок, есть только два подхода:

1.) Ваш подход с ConcurrentHashMap

  • Override равен и hashCode в SoftReference
  • Внутри равен и hashCode только доступ к объекту с помощью SoftReference # get
  • Поместите SoftReference в качестве ключа, а любой объект в качестве значения (только null не допускается)
  • Если ссылка устарела, пока обращаясь к hashCode или равно, добавьте ссылку на очередь удаления, чтобы часто удалять мертвые ключи.
  • Проверьте наличие через containsKey

2.) Используйте ConcurrentMultimap > и используйте hashCode в качестве ключа и синхронизированный набор SoftReferences в качестве значений. Когда вы получите попадание hashCode , проверьте содержимое всех SoftReferences на равенство. Не очень красиво, согласен и сложно синхронизировать.

На вашем месте я бы вообще не использовал SoftReferences, а скорее ConcurrentHashMap для надежных ссылок на ваши POJO. Каждый раз, когда прибывает новый элемент, также помещайте его в ConcurrentLinkQueue. Если очередь превышает определенный предел, начните удалять элементы из HashMap.

1
ответ дан 5 December 2019 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: