Попытка создать Bi-карту Spark, состоящую из двух карт. Поскольку отображения уникальны с любого направления, все, что должно быть сериализовано, представляет собой единую карту, на самом деле нужно сериализовать только a Seq [(K, V)]. Таким образом, лежат только основные элементы карты. В десериализации мы можем воссоздать обратную карту и индексы.Серийная трансляция серийного программирования BiMap класса
Вот предлагаемая конструкция:
class BiMap[K, V] (
private val m: Map[K, V],
// if this is serialized we allow i to be discarded and recalculated when deserialized
@transient private var i: Option[BiMap[V, K]] = None
) extends Serializable {
// NOTE: make inverse's inverse point back to current BiMap
// if this is serialized we allow inverse to be discarded and recalculated
// when first invoked from "val size_" in the constructor
@transient lazy val inverse: BiMap[V, K] = {
if(i == null.asInstanceOf[Option[BiMap[V, K]]])
i = None
i.getOrElse {
val rev = m.map(_.swap)
require((rev.size == m.size), "Failed to create reversed map. Cannot have duplicated values.")
new BiMap(rev, Some(this))
}
}
// forces inverse to be calculated in the constructor when deserialized
// not when first used
@transient val size_ = inverse.size
...
}
Хотя это похоже на работу, я не могу понять, почему я должен проверить i
на нуль, но нуль после десериализации. Первоначально это был val, который имел инициализацию по умолчанию = None.
только м следует сериализовать поэтому обратное @transient lazy
и есть другой @transient val size_ = inverse.size
, который предназначен, чтобы вызвать обратный быть оценено при десериализации (вместо того, чтобы, когда задача вызывает inverse
). Этот последний бит состоит в том, чтобы убедиться, что обратная связь является общей и не воссоздана каждой задачей.
Хотя это, кажется, работает это немного некрасиво, и я до сих пор не уверен в несколько вещей:
- все для хранения экземпляра, выделенного в переменном вещании, а не в задачах кучи пространства?
- Почему
i
должен быть var и проверен на null, когда он никогда не должен быть пустым? - Самое главное, что это означает, что инверсия будет отброшена во время вещания и воссоздана в десериализовании?
Я понимаю, что мне нужно зарегистрировать это с помощью Kryo и в конечном итоге реализовать KryoSerializable, чтобы точно контролировать сериализацию.
Хорошо, у меня есть так регистратор может легко зарегистрировать класс. Это означает, что он будет использовать интерфейс Serializable, если я не реализую KryoSerializable. Я отредактирую вопрос, чтобы задать ответ. – pferrel
Нет, это означает, что вы будете использовать Serailizable, если вы не зарегистрируете свои классы в KryoRegistrator. Если вам не нравится поведение по умолчанию, вы можете реализовать интерфейс KryoSerializable, чтобы иметь собственную сериализацию ... – mgaido