Предпочтительный способ обработки этих данных с параллельными массивами - PullRequest
2 голосов
/ 11 мая 2011

Представьте себе последовательность java.io.File объектов.Последовательность не в каком-то определенном порядке, она заполняется после обхода каталога.Имена файлов могут быть такими:

/some/file.bin
/some/other_file_x1.bin
/some/other_file_x2.bin
/some/other_file_x3.bin
/some/other_file_x4.bin
/some/other_file_x5.bin
...
/some/x_file_part1.bin
/some/x_file_part2.bin
/some/x_file_part3.bin
/some/x_file_part4.bin
/some/x_file_part5.bin
...
/some/x_file_part10.bin

В принципе, я могу иметь 3 типа файлов.Первый тип - простые, которые имеют расширение .bin.Второй тип файлов - это файл, сформированный от _x1.bin до _x5.bin.И третий тип файла может быть сформирован из 10 меньших частей, от _part1 до _part10.Я знаю, что названия могут быть странными, но это то, с чем я должен работать:)

Я хочу сгруппировать файлы вместе (все части файла должны быть обработаны вместе), и я думал оиспользуя параллельные массивы, чтобы сделать это.В чем я не уверен, так это в том, как я могу выполнить часть уменьшения / накопления, так как все потоки будут работать с одним и тем же массивом.

val allBinFiles = allBins.toArray // array of java.io.File

Я думал об обработке чего-то подобного:

val mapAcumulator = java.util.Collections.synchronizedMap[String,ListBuffer[File]](new java.util.HashMap[String,ListBuffer[File]]())

allBinFiles.par.foreach { file =>
   file match {
      // for something like /some/x_file_x4.bin nameTillPart will be /some/x_file
      case ComposedOf5Name(nameTillPart) => {
          mapAcumulator.getOrElseUpdate(nameTillPart,new ListBuffer[File]()) += file
      }
      case ComposedOf10Name(nameTillPart) => {
          mapAcumulator.getOrElseUpdate(nameTillPart,new ListBuffer[File]()) += file
      }
      // simple file, without any pieces
      case _ => {
          mapAcumulator.getOrElseUpdate(file.toString,new ListBuffer[File]()) += file
      }
   }
}

Я думал сделать это так, как я показал в приведенном выше коде.Наличие экстракторов для файлов и использование части пути в качестве ключа на карте.Как, например, /some/x_file может содержать значения от /some/x_file_x1.bin до /some/x_file_x5.bin.Я также думаю, что может быть лучший способ справиться с этим.Мне было бы интересно ваше мнение.

1 Ответ

1 голос
/ 11 мая 2011

Альтернативой является использование groupBy:

val mp = allBinFiles.par.groupBy {
  case ComposedOf5Name(x) => x
  case ComposedOf10Name(x) => x
  case f => f.toString
}

Это вернет параллельную карту параллельных массивов файлов (ParMap[String, ParArray[File]]). Если вам нужна последовательная карта последовательных последовательностей файлов из этой точки:

val sqmp = mp.map(_.seq).seq

Чтобы обеспечить параллелизм, убедитесь, что в параллельном массиве достаточно элементов (10k +).

...