Java, создающий массив байтов, размер которого представлен длинным

В итоге я сделал патч обезьяны, который переопределяет классовые методы Mongoid embeds_many и embeds_one, чтобы также определить метод экземпляра для очистки несохраненных документов для этого отношения. Мне показалось, что это самый простой способ, потому что это очень мало кода, и это означает, что мне не нужно помнить, чтобы включать его местами.

# config/initializers/patches/dirty_tracking_embedded.rb
module DirtyTrackingEmbedded
    # override the embedding methods to also make dirty-tracking
    def embeds_many(name, options= {}, &block)
        define_method "clear_unsaved_#{name}" do
            new_list = send(name).select(&:persisted?)
            send(name.to_s + "=", new_list)
        end
        super
    end

    def embeds_one(name, options={}, &block)
        define_method "clear_unsaved_#{name}" do
            send(name.to_s + "=", nil) unless send(name).persisted?
        end
        super
    end
end

module Mongoid
    module Association
        module Macros
            module ClassMethods
                prepend DirtyTrackingEmbedded
            end
        end
    end
end

Затем в моем контроллере я использовал after_action:

# app/controllers/relationships_controller.rb
class RelationshipsController < ApplicationController
    after_action :clear_unsaved, only: [:new]

    def new
        @relationship = current_user.relationships.new(friend_id: params[:fid])
        @relationship.validate
    end

    private
    def clear_unsaved
        current_user.clear_unsaved_relationships
    end
end

Другие возможности

Другой патч обезьяны

Вы можете патчить обезьяну [ 115] методы в Mongoid::Association::Embedded::EmbedsMany и Mongoid::Association::Embedded::EmbedsOne , чтобы включить настройку метода экземпляра для очистки несохраненных. Вы можете найти пример того, как монгоиды делают подобные вещи, посмотрев на Mongoid::Association::Accessors#self.define_ids_setter! . Я бы порекомендовал сделать ваше исправление с помощью prepend, как в решении, которое я использовал, чтобы вы могли наследовать остальную часть метода.

Патч и наследование Combo Monkey

Mongoid выбирает, какой класс использовать для создания ассоциации из константы с именем MACRO_MAPPING в Mongoid::Association , так что вы можете создавать классы, которые наследуются от EmbedsMany и EmbedsOne просто переопределяют setup_instance_methods!, чтобы добавить необходимый метод экземпляра, тогда вам нужно будет только обезьяна заплатить MACRO_MAPPING для сопоставления с вашими новыми классами.

Обеспокоенность

Если вы исправляете ошибки от обезьян, вы можете использовать код из моего модуля DirtyTrackingEmbedded, чтобы создать ActiveSupport::Concern, который делает то же самое. Вы захотите поместить переопределенные методы в блок class_methods, а затем просто убедитесь, что вы включили этот модуль после включения Mongoid::Document в любой класс модели, в котором вы хотите его использовать.

26
задан Nayuki 19 January 2016 в 21:18
поделиться

5 ответов

(Вероятно, это немного поздно для OP, но все же может быть полезно для других)

К сожалению, Java не поддерживает массивы с более чем 2 31 < / sup> -1 элементов. Максимальное потребление составляет 2 ГБ пространства для массива byte[] или 16 ГБ пространства для массива long[].

Хотя это, вероятно, неприменимо в этом случае, если массив будет разреженным , вы можете избежать использования ассоциативной структуры данных, такой как Map , чтобы сопоставить каждое использованное смещение с соответствующим значением. Кроме того, Trove обеспечивает более эффективную реализацию памяти для хранения примитивных значений, чем стандартные коллекции Java.

Если массив не разреженный и вам действительно нужен весь блоб в памяти, вам, вероятно, придется использовать двумерную структуру, например, с Map совпадающими смещениями по модулю 1024 в соответствующий 1024-байтовый массив. Этот подход может быть более эффективным с точки зрения памяти даже для разреженных массивов, поскольку смежные заполненные ячейки могут использовать одну и ту же запись Map.

23
ответ дан Robert 28 November 2019 в 07:49
поделиться

Это не из немедленной помощи, но создание массивов с большими размерами (через longs) является предлагаемым изменением языка для Java 7. Ознакомьтесь с предложениями Project Coin для получения дополнительной информации

1
ответ дан Brian Agnew 28 November 2019 в 07:49
поделиться

Байт [] с размером максимального 32-битного целого числа со знаком потребует 2 ГБ непрерывного адресного пространства. Не стоит пытаться создать такой массив. В противном случае, если размер на самом деле не такой большой (а это просто больший тип), вы можете безопасно преобразовать его в int и использовать его для создания массива.

6
ответ дан 28 November 2019 в 07:49
поделиться

Вам, вероятно, следует использовать поток для чтения ваших данных, а другой - для их записи вне. Если вам понадобится доступ к данным позже в файле, сохраните их. Если вам нужен доступ к чему-то, с чем вы еще не сталкивались, вам нужна двухпроходная система, в которой вы проходите один раз и сохраняете «материал, который вам понадобится для второго прохода, а затем проходите снова».

Компиляторы работайте таким образом.

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

Класс-контейнер будет иметь массив байтовых массивов, но извне все обращения кажутся смежными. Вы просто запросите байт 49874329128714391837, и ваш класс разделит ваш Long на размер каждого байтового массива, чтобы вычислить, к какому массиву получить доступ, затем используйте остаток для определения байта.

Он также может иметь методы для хранения и извлечения «фрагментов», которые могут охватывать границы байтового массива, что потребует создания временной копии, но затраты на создание нескольких временных массивов будут быть более чем компенсированным тем фактом, что у вас нет выделенного заблокированного 2 ГБ пространства, что, как я думаю, может просто испортить вашу производительность.

Edit: ps. Если вам действительно нужен произвольный доступ и вы не можете использовать потоки, тогда реализация содержащего класса является очень хорошей идеей. Это позволит вам на лету менять реализацию с однобайтового массива на группу байтовых массивов на файловую систему без каких-либо изменений в остальной части вашего кода.

который мог бы охватывать границы байтового массива, что потребовало бы создания временной копии, но затраты на создание нескольких временных массивов были бы более чем компенсированы тем фактом, что у вас нет выделенного заблокированного 2 ГБ пространства, которое, как я думаю, могло бы просто разрушьте вашу производительность.

Edit: ps. Если вам действительно нужен произвольный доступ и вы не можете использовать потоки, тогда реализация содержащего класса является очень хорошей идеей. Это позволит вам на лету менять реализацию с однобайтового массива на группу байтовых массивов на файловую систему без каких-либо изменений в остальной части вашего кода.

который мог бы охватывать границы байтового массива, что потребовало бы создания временной копии, но затраты на создание нескольких временных массивов были бы более чем компенсированы тем фактом, что у вас нет выделенного заблокированного 2 ГБ пространства, которое, как я думаю, могло бы просто разрушьте вашу производительность.

Edit: ps. Если вам действительно нужен произвольный доступ и вы не можете использовать потоки, тогда реализация содержащего класса является очень хорошей идеей. Это позволит вам на лету менять реализацию с однобайтового массива на группу байтовых массивов на файловую систему без каких-либо изменений в остальной части вашего кода.

Если вам действительно нужен произвольный доступ и вы не можете использовать потоки, тогда реализация содержащего класса является очень хорошей идеей. Это позволит вам на лету менять реализацию с однобайтового массива на группу байтовых массивов на файловую систему без каких-либо изменений в остальной части вашего кода.

Если вам действительно нужен произвольный доступ и вы не можете использовать потоки, тогда реализация содержащего класса является очень хорошей идеей. Это позволит вам на лету менять реализацию с однобайтового массива на группу байтовых массивов на файловую систему без каких-либо изменений в остальной части вашего кода.

1
ответ дан 28 November 2019 в 07:49
поделиться

Один из способов «сохранить» массив - это записать его в файл и затем получить к нему доступ (если вам нужен доступ к нему как к массиву) с помощью RandomAccessFile. API для этого файла использует long как индекс в файле вместо int. Это будет медленнее, но с меньшей нагрузкой на память.

Это когда вы не можете извлечь то, что вам нужно во время начального сканирования ввода.

0
ответ дан 28 November 2019 в 07:49
поделиться
Другие вопросы по тегам:

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