<commit_before>//
//  CompoundDataAdapter.swift
//  ModelsTreeDemo
//
//  Created by Aleksey on 11.12.16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

public class CompoundDataAdapter<ObjectType> : ObjectsDataSource<ObjectType> where ObjectType: Equatable, ObjectType: Hashable {
  
  public typealias ContainedDataSourceType = ObjectsDataSource<ObjectType>
  
  private let pool = AutodisposePool()
  private let dataSources: [ContainedDataSourceType]
  
  public init(dataSources: [ContainedDataSourceType]) {
    self.dataSources = dataSources
    
    super.init()
    
    subscribeForUpdates(inSources: dataSources)
  }
  
  // MARK: - Access to objects and sections
  
  public override func numberOfSections() -> Int {
    return dataSources.reduce(0) { totalNumberOfSections, dataSource in
      totalNumberOfSections + dataSource.numberOfSections() }
  }
  
  public override func numberOfObjectsInSection(_ section: Int) -> Int {
    let flatSection = flatSections()[section]!
    return flatSection.dataSource.numberOfObjectsInSection(flatSection.relativeSectionIndex)
  }
  
  public override func objectAtIndexPath(_ indexPath: IndexPath) -> ObjectType? {
    let flatSection = flatSections()[indexPath.section]!
    return flatSection.dataSource.objectAtIndexPath(IndexPath(row: indexPath.row, section: flatSection.relativeSectionIndex))
  }
  
  // MARK: - Helpers
  
  private func flatSections() -> [Int: (relativeSectionIndex: Int, dataSource: ContainedDataSourceType)] {
    var result = [Int: (relativeSectionIndex: Int, dataSource: ContainedDataSourceType)]()
    var sectionsPassed = 0
    for source in dataSources {
      for i in 0..<source.numberOfSections() {
        result[i + sectionsPassed] = (relativeSectionIndex: i, dataSource: source)
      }
      sectionsPassed += source.numberOfSections()
    }
    return result
  }
  
  private func subscribeForUpdates(inSources sources: [ContainedDataSourceType]) {
    sources.forEach { source in
      source.beginUpdatesSignal.subscribeNext { [weak self] in
        self?.beginUpdatesSignal.sendNext()
      }.putInto(pool)
      
      source.endUpdatesSignal.subscribeNext { [weak self] in
        self?.endUpdatesSignal.sendNext()
      }.putInto(pool)<commit_msg>simplified flat sections<commit_after>//
//  CompoundDataAdapter.swift
//  ModelsTreeDemo
//
//  Created by Aleksey on 11.12.16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

public class CompoundDataAdapter<ObjectType> : ObjectsDataSource<ObjectType> where ObjectType: Equatable, ObjectType: Hashable {
  
  public typealias ContainedDataSourceType = ObjectsDataSource<ObjectType>
  
  private let pool = AutodisposePool()
  private let dataSources: [ContainedDataSourceType]
  
  public init(dataSources: [ContainedDataSourceType]) {
    self.dataSources = dataSources
    
    super.init()
    
    subscribeForUpdates(inSources: dataSources)
  }
  
  // MARK: - Access to objects and sections
  
  public override func numberOfSections() -> Int {
    return dataSources.reduce(0) { totalNumberOfSections, dataSource in
      totalNumberOfSections + dataSource.numberOfSections() }
  }
  
  public override func numberOfObjectsInSection(_ section: Int) -> Int {
    let flatSection = flatSections()[section]
    return flatSection.dataSource.numberOfObjectsInSection(flatSection.relativeSectionIndex)
  }
  
  public override func objectAtIndexPath(_ indexPath: IndexPath) -> ObjectType? {
    let flatSection = flatSections()[indexPath.section]
    return flatSection.dataSource.objectAtIndexPath(IndexPath(row: indexPath.row, section: flatSection.relativeSectionIndex))
  }
  
  // MARK: - Helpers
  
  private func flatSections() -> [(relativeSectionIndex: Int, dataSource: ContainedDataSourceType)] {
    var result = [(relativeSectionIndex: Int, dataSource: ContainedDataSourceType)]()
    var sectionsPassed = 0
    for source in dataSources {
      for i in 0..<source.numberOfSections() {
        result.append((relativeSectionIndex: i, dataSource: source))
      }
      sectionsPassed += source.numberOfSections()
    }
    return result
  }
  
  private func subscribeForUpdates(inSources sources: [ContainedDataSourceType]) {
    sources.forEach { source in
      source.beginUpdatesSignal.subscribeNext { [weak self] in
        self?.beginUpdatesSignal.sendNext()
      }.putInto(pool)
      
      source.endUpdatesSignal.subscribeNext { [weak self] in
        self?.endUpdatesSignal.sendNext()
      }.putInto(pool)
{'fraction_non_alphanumeric': 0.0928335170893054, 'fraction_numerical': 0.005733186328555678, 'mean_word_length': 3.8879310344827585, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4887593', 'n_tokens_mistral': 1317, 'n_tokens_neox': 1264, 'n_words': 295}