<commit_before>//
//  FetchedResultsController.swift
//  CollectionView
//
//  Created by <NAME> on 1/16/17.
//  Copyright © 2017 Noun Project. All rights reserved.
//

import Foundation




fileprivate struct ChangeContext<Element:NSManagedObject> : CustomStringConvertible {
    
    var objectChanges = ObjectChangeSet<IndexPath, Element>()
    var itemsWithSectionChange = Set<Element>()
    
    mutating func reset() {
        self.objectChanges.reset()
    }
    
    var description: String {
        return "Context Items: \(objectChanges.deleted.count) Deleted, \(objectChanges.inserted.count) Inserted, \(objectChanges.updated.count) Updated"
    }
}





public typealias SectionRepresentable = Comparable & Hashable & CustomDisplayStringConvertible

fileprivate class FetchedSectionInfo<ValueType: SectionRepresentable, Element: NSManagedObject>: NSObject, Comparable, ResultsControllerSectionInfo {
    
    public var object : Any? { return self._value }
    public var objects: [Any] { return _storage.objects }
    
    public var numberOfObjects : Int { return _storage.count }
    
    private(set) var _value : ValueType?
    private(set) var _storage = OrderedSet<Element>()
    private(set) var _storageCopy = OrderedSet<Element>()
    
    internal init(value: ValueType?, objects: [Element] = []) {
        self._value = value
        _storage.add(contentsOf: objects)
    }
    
    
    
    // MARK: - Equatable
    /*-------------------------------------------------------------------------------*/
    override public var hashValue: Int {
        return _value?.hashValue ?? 0
    }
    fileprivate override func isEqual(_ object: Any?) -> Bool {
        return self._value == (object as? FetchedSectionInfo<ValueType, Element>)?._value
    }
    public static func ==(lhs: FetchedSectionInfo, rhs: FetchedSectionInfo) -> Bool {
        return lhs._value == rhs._value
    }
    static func <(lhs: FetchedSectionInfo, rhs: FetchedSectionInfo) -> Bool {
        if let v1 = lhs._value,
            let v2 = rhs._value {
            return v1 < v2
        }
        return lhs._value != nil
    }
    
    
    // MARK: - Objects
    /*-------------------------------------------------------------------------------*/
    
    func index(of object: Element) -> Int? {
        return _storage.index(of: object)
    }
    
    @discardableResult func insert(_ object: Element, using sortDescriptors: [NSSortDescriptor] = []) -> Int {
        
        if self._storage.count == 0  {
            self.add(object)
            return 0
        }
        else if needsSort || sortDescriptors.count == 0 {
            self.add(object)
            return self._storage.count - 1
        }
        else {
            let idx = _storage.insert(object, using: sortDescriptors)
            return idx
        }
    }
    @discardableResult func remove(_ object: Element) -> Int? {
        return _storage.remove(object)
    }
    
    func sortItems(using sortDescriptors: [NSSortDescriptor]) {
        self.needsSort = false
        self._storage.sort(using: sortDescriptors)
    }
    func sort(using sorter: FetchedResultsController<ValueType, Element>.Sorter) {
        self._storage.sort(by: { (e1, e2) -> Bool in
            return sorter(e1, e2)
        })
    }
    
    
    // MARK: - Editing
    /*-------------------------------------------------------------------------------*/
    
    private(set) var needsSort : Bool = false
    private(set) var isEditing: Bool = false
//    private var _added = Set<Element>() // Tracks added items needing sort, if one do insert for performance
    
    func beginEditing() {
        assert(!isEditing, "Mutiple calls to beginEditing() for RelationalResultsControllerSection")
        isEditing = true
        _storageCopy = _storage
//        _added.removeAll()
    }
    
    func ensureEditing() {
        if isEditing { return }
        beginEditing()
    }
    
    func endEditing(forceUpdates: Set<Element>) -> ChangeSet<OrderedSet<Element>> {
        assert(isEditing, "endEditing() called before beginEditing() for RelationalResultsControllerSection")
        assert(!needsSort, "endEditing() called but the section still needs to be sorted.")
        isEditing = false
        self.needsSort = false
        let changes = ChangeSet(source: _storageCopy, target: _storage, forceUpdates: forceUpdates)
        self._storageCopy.removeAll()
        return changes
    }
    
    func markNeedsSort() {
        self.needsSort = true
    }
    
    func add(_ element: Element) {
        guard self._storage.contains(element) == false else {
            let _ = _storage.index(of: element)
            return
        }
        self.needsSort = self._storage.count > 0
//        _added.insert(element)
        self._storage.add(element)
    }

    
}



/**
 An item based results controller
*/
public class FetchedResultsController<Section: SectionRepresentable, Element: NSManagedObject> : NSObject, ResultsController {
    
    
    fileprivate typealias SectionInfo = FetchedSectionInfo<Section, Element>
    
    // MARK: - Results Controller Protocol
    /*-------------------------------------------------------------------------------*/
    
    public var allObjects: [Any] { return Array(fetchedObjects) }
    public var sections: [ResultsControllerSectionInfo] { return _sections.objects }
    
    public var hasEmptyPlaceholder : Bool = false
    
    public let fetchRequest : NSFetchRequest<Element>
    public var sortDescriptors: [NSSortDescriptor]? {
        return fetchRequest.sortDescriptors
    }
    public unowned let managedObjectContext: NSManagedObjectContext
    <commit_msg>Minor fix to needsSort for FetchedResultsController<commit_after>//
//  FetchedResultsController.swift
//  CollectionView
//
//  Created by <NAME> on 1/16/17.
//  Copyright © 2017 Noun Project. All rights reserved.
//

import Foundation




fileprivate struct ChangeContext<Element:NSManagedObject> : CustomStringConvertible {
    
    var objectChanges = ObjectChangeSet<IndexPath, Element>()
    var itemsWithSectionChange = Set<Element>()
    
    mutating func reset() {
        self.objectChanges.reset()
    }
    
    var description: String {
        return "Context Items: \(objectChanges.deleted.count) Deleted, \(objectChanges.inserted.count) Inserted, \(objectChanges.updated.count) Updated"
    }
}





public typealias SectionRepresentable = Comparable & Hashable & CustomDisplayStringConvertible

fileprivate class FetchedSectionInfo<ValueType: SectionRepresentable, Element: NSManagedObject>: NSObject, Comparable, ResultsControllerSectionInfo {
    
    public var object : Any? { return self._value }
    public var objects: [Any] { return _storage.objects }
    
    public var numberOfObjects : Int { return _storage.count }
    
    private(set) var _value : ValueType?
    private(set) var _storage = OrderedSet<Element>()
    private(set) var _storageCopy = OrderedSet<Element>()
    
    internal init(value: ValueType?, objects: [Element] = []) {
        self._value = value
        _storage.add(contentsOf: objects)
    }
    
    
    
    // MARK: - Equatable
    /*-------------------------------------------------------------------------------*/
    override public var hashValue: Int {
        return _value?.hashValue ?? 0
    }
    fileprivate override func isEqual(_ object: Any?) -> Bool {
        return self._value == (object as? FetchedSectionInfo<ValueType, Element>)?._value
    }
    public static func ==(lhs: FetchedSectionInfo, rhs: FetchedSectionInfo) -> Bool {
        return lhs._value == rhs._value
    }
    static func <(lhs: FetchedSectionInfo, rhs: FetchedSectionInfo) -> Bool {
        if let v1 = lhs._value,
            let v2 = rhs._value {
            return v1 < v2
        }
        return lhs._value != nil
    }
    
    
    // MARK: - Objects
    /*-------------------------------------------------------------------------------*/
    
    func index(of object: Element) -> Int? {
        return _storage.index(of: object)
    }
    
    @discardableResult func insert(_ object: Element, using sortDescriptors: [NSSortDescriptor] = []) -> Int {
        
        if self._storage.count == 0  {
            self.add(object)
            return 0
        }
        else if needsSort || sortDescriptors.count == 0 {
            self.add(object)
            return self._storage.count - 1
        }
        else {
            let idx = _storage.insert(object, using: sortDescriptors)
            return idx
        }
    }
    @discardableResult func remove(_ object: Element) -> Int? {
        return _storage.remove(object)
    }
    
    func sortItems(using sortDescriptors: [NSSortDescriptor]) {
        self.needsSort = false
        self._storage.sort(using: sortDescriptors)
    }
    func sort(using sorter: FetchedResultsController<ValueType, Element>.Sorter) {
        self._storage.sort(by: { (e1, e2) -> Bool in
            return sorter(e1, e2)
        })
    }
    
    
    // MARK: - Editing
    /*-------------------------------------------------------------------------------*/
    
    private(set) var needsSort : Bool = false
    private(set) var isEditing: Bool = false
//    private var _added = Set<Element>() // Tracks added items needing sort, if one do insert for performance
    
    func beginEditing() {
        assert(!isEditing, "Mutiple calls to beginEditing() for RelationalResultsControllerSection")
        isEditing = true
        _storageCopy = _storage
//        _added.removeAll()
    }
    
    func ensureEditing() {
        if isEditing { return }
        beginEditing()
    }
    
    func endEditing(forceUpdates: Set<Element>) -> ChangeSet<OrderedSet<Element>> {
        assert(isEditing, "endEditing() called before beginEditing() for RelationalResultsControllerSection")
        assert(!needsSort, "endEditing() called but the section still needs to be sorted.")
        isEditing = false
        self.needsSort = false
        let changes = ChangeSet(source: _storageCopy, target: _storage, forceUpdates: forceUpdates)
        self._storageCopy.removeAll()
        return changes
    }
    
    func markNeedsSort() {
        self.needsSort = true
    }
    
    func add(_ element: Element) {
        guard self._storage.contains(element) == false else {
            let _ = _storage.index(of: element)
            return
        }
        
        self.needsSort = self.needsSort || self._storage.count > 0
//        _added.insert(element)
        self._storage.add(element)
    }

    
}



/**
 An item based results controller
*/
public class FetchedResultsController<Section: SectionRepresentable, Element: NSManagedObject> : NSObject, ResultsController {
    
    
    fileprivate typealias SectionInfo = FetchedSectionInfo<Section, Element>
    
    // MARK: - Results Controller Protocol
    /*-------------------------------------------------------------------------------*/
    
    public var allObjects: [Any] { return Array(fetchedObjects) }
    public var sections: [ResultsControllerSectionInfo] { return _sections.objects }
    
    public var hasEmptyPlaceholder : Bool = false
    
    public let fetchRequest : NSFetchRequest<Element>
    public var sortDescriptors: [NSSortDescriptor]? {
        return fetchRequest.sortDescriptors
    }
    public unowned let managedObjectContext: NSManagedObjectContext
    
{'fraction_non_alphanumeric': 0.1453605537544905, 'fraction_numerical': 0.004030491544729694, 'mean_word_length': 2.0633387010198603, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 53, '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': '2757291', 'n_tokens_mistral': 3098, 'n_tokens_neox': 3020, 'n_words': 772}