<commit_before>//
//  RegularGrid.swift
//  SmoothedParticleHydrodynamics
//
//  Created by <NAME> on 8/26/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

protocol CellObjectProtocol {
    var x: CGPoint { get }
}

internal class Cell<ObjectType> {
    var count: Int = 0
    var firstIndex: Int = 0
    var objects: UnsafeMutablePointer<ObjectType> = nil // todo: remove, it's not strictly necessary to have this pointer
    func insert(object: ObjectType) {
        objects[count] = object
        count += 1
    }
}

class RegularGrid<ObjectType: CellObjectProtocol>  {
    
    let width: Double
    let height: Double
    
    let objects: UnsafeMutablePointer<ObjectType>
    let objectData: NSData
    var numObjects: Int
    let maxObjects: Int

    let cells: UnsafeMutablePointer<Cell<ObjectType>>
    let cellData: NSData
    let horizontalCells: Int
    let verticalCells: Int
    var numCells: Int {
        return horizontalCells * verticalCells
    }
    
    let cellSize: Double
    let cellStride: Int // offset to add per row when indexing into cells
    
    required init(withWidth width: Double, height: Double, cellSize: Double, maxObjects: Int) {
        
        assert(cellSize > 0)
        
        self.width = width
        self.height = height
        self.cellSize = cellSize
        
        self.horizontalCells = Int(ceil(width / cellSize))
        self.verticalCells = Int(ceil(height / cellSize))
        let numCells = self.horizontalCells * self.verticalCells
        self.cellStride = self.horizontalCells
        
        self.objectData = NSMutableData(length: sizeof(ObjectType) * maxObjects )! // zero-filled per documentation
        self.objects = UnsafeMutablePointer<ObjectType>(objectData.bytes)

        self.cellData = NSMutableData(length: sizeof(Cell<ObjectType>) * numCells )! // zero-filled per documentation
        self.cells = UnsafeMutablePointer<Cell<ObjectType>>(cellData.bytes)

        self.numObjects = 0
        self.maxObjects = maxObjects
        
    }
    
    func cell(atLocation location: CGPoint) -> Cell<ObjectType> {
       
        assert((Double(location.x) >= 0) && (Double(location.x) <= self.width))
        assert((Double(location.y) >= 0) && (Double(location.y) <= self.height))

        let horizontalIndex: Int = Int(floor(Double(location.x) / cellSize))
        let verticalIndex: Int   = Int(floor(Double(location.y) / cellSize))
        
        return self.cell(atHorizontalIndex: horizontalIndex, verticalIndex: verticalIndex)
        
    }
    
    func cell(atHorizontalIndex horizontalIndex: Int, verticalIndex: Int) -> Cell<ObjectType> {
        assert(horizontalIndex > 0 && horizontalIndex < self.horizontalCells)
        assert(verticalIndex > 0 && verticalIndex < self.verticalCells)
        let index = verticalIndex * self.cellStride + horizontalIndex
        return self.cells[index]
    }
    
    func setObjects(objects: [ObjectType]) {
        assert(objects.count < self.maxObjects)
        // step 1: update counts for all cells
        for object in objects {
            let cell = self.cell(atLocation: object.x)
            cell.count += 1
        }
        // step 2: use counts to allocate memory for cells and reset counts
        var numObjectsSoFar: Int = 0
        for i in 0..<self.numCells {
            cells[i].objects = self.objects + numObjectsSoFar // pointer arithmetic
            cells[i].firstIndex = numObjectsSoFar
            numObjectsSoFar += cells[i].count
            cells[i].count = 0 // we have to reset this because cell.insert uses it to determine what index to use when inserting
        }
        // step 3: insert objects
        for object in objects {
            let cell = self.cell(atLocation: object.x)
            cell.insert(object)
        }
        // step 4: update object count
        self.numObjects = numObjectsSoFar
    }
    
    // todo: copy object list function 
    
    func generateObjectsByApplyingSpacialFunction(nextObjects: UnsafeMutablePointer<ObjectType>,
                maxDistance: Double,
                applyCallback: (index1: Int, index2: Int, objects: UnsafeMutablePointer<ObjectType>, referenceObject: ObjectType, otherObject: ObjectType ) -> Void

        ) {
        
        let cellsToCheck: Int = Int(ceil(maxDistance / self.cellSize))
        
        for objectIndex1 in 0..<self.numObjects {

            let object1: ObjectType = self.objects[objectIndex1]
            let horizontalCellIndex: Int = Int(floor(Double(object1.x.x) / cellSize))
            let verticalCellIndex: Int   = Int(floor(Double(object1.x.y) / cellSize))

            // check the cells above (and equal row) as well as to the left (up to equal column)
            // these have object indices that are less than or equal to object1 cell's object indices
            // when we compare the two objects may actually be in the same cell
            // in this case we take care to ensure that object2's index is less than object1's
<commit_msg>updated comment.<commit_after>//
//  RegularGrid.swift
//  SmoothedParticleHydrodynamics
//
//  Created by <NAME> on 8/26/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

protocol CellObjectProtocol {
    var x: CGPoint { get }
}

internal class Cell<ObjectType> {
    var count: Int = 0
    var firstIndex: Int = 0
    var objects: UnsafeMutablePointer<ObjectType> = nil // todo: remove, it's not strictly necessary to have this pointer
    func insert(object: ObjectType) {
        objects[count] = object
        count += 1
    }
}

class RegularGrid<ObjectType: CellObjectProtocol>  {
    
    let width: Double
    let height: Double
    
    let objects: UnsafeMutablePointer<ObjectType>
    let objectData: NSData
    var numObjects: Int
    let maxObjects: Int

    let cells: UnsafeMutablePointer<Cell<ObjectType>>
    let cellData: NSData
    let horizontalCells: Int
    let verticalCells: Int
    var numCells: Int {
        return horizontalCells * verticalCells
    }
    
    let cellSize: Double
    let cellStride: Int // offset to add per row when indexing into cells
    
    required init(withWidth width: Double, height: Double, cellSize: Double, maxObjects: Int) {
        
        assert(cellSize > 0)
        
        self.width = width
        self.height = height
        self.cellSize = cellSize
        
        self.horizontalCells = Int(ceil(width / cellSize))
        self.verticalCells = Int(ceil(height / cellSize))
        let numCells = self.horizontalCells * self.verticalCells
        self.cellStride = self.horizontalCells
        
        self.objectData = NSMutableData(length: sizeof(ObjectType) * maxObjects )! // zero-filled per documentation
        self.objects = UnsafeMutablePointer<ObjectType>(objectData.bytes)

        self.cellData = NSMutableData(length: sizeof(Cell<ObjectType>) * numCells )! // zero-filled per documentation
        self.cells = UnsafeMutablePointer<Cell<ObjectType>>(cellData.bytes)

        self.numObjects = 0
        self.maxObjects = maxObjects
        
    }
    
    func cell(atLocation location: CGPoint) -> Cell<ObjectType> {
       
        assert((Double(location.x) >= 0) && (Double(location.x) <= self.width))
        assert((Double(location.y) >= 0) && (Double(location.y) <= self.height))

        let horizontalIndex: Int = Int(floor(Double(location.x) / cellSize))
        let verticalIndex: Int   = Int(floor(Double(location.y) / cellSize))
        
        return self.cell(atHorizontalIndex: horizontalIndex, verticalIndex: verticalIndex)
        
    }
    
    func cell(atHorizontalIndex horizontalIndex: Int, verticalIndex: Int) -> Cell<ObjectType> {
        assert(horizontalIndex > 0 && horizontalIndex < self.horizontalCells)
        assert(verticalIndex > 0 && verticalIndex < self.verticalCells)
        let index = verticalIndex * self.cellStride + horizontalIndex
        return self.cells[index]
    }
    
    func setObjects(objects: [ObjectType]) {
        assert(objects.count < self.maxObjects)
        // step 1: update counts for all cells
        for object in objects {
            let cell = self.cell(atLocation: object.x)
            cell.count += 1
        }
        // step 2: use counts to allocate memory for cells and reset counts
        var numObjectsSoFar: Int = 0
        for i in 0..<self.numCells {
            cells[i].objects = self.objects + numObjectsSoFar // pointer arithmetic
            cells[i].firstIndex = numObjectsSoFar
            numObjectsSoFar += cells[i].count
            cells[i].count = 0 // we have to reset this because cell.insert uses it to determine what index to use when inserting
        }
        // step 3: insert objects
        for object in objects {
            let cell = self.cell(atLocation: object.x)
            cell.insert(object)
        }
        // step 4: update object count
        self.numObjects = numObjectsSoFar
    }
    
    // todo: copy object list function 
    
    func generateObjectsByApplyingSpacialFunction(nextObjects: UnsafeMutablePointer<ObjectType>,
                maxDistance: Double,
                applyCallback: (index1: Int, index2: Int, objects: UnsafeMutablePointer<ObjectType>, referenceObject: ObjectType, otherObject: ObjectType ) -> Void

        ) {
        
        let cellsToCheck: Int = Int(ceil(maxDistance / self.cellSize))
        
        for objectIndex1 in 0..<self.numObjects {

            let object1: ObjectType = self.objects[objectIndex1]
            let horizontalCellIndex: Int = Int(floor(Double(object1.x.x) / cellSize))
            let verticalCellIndex: Int   = Int(floor(Double(object1.x.y) / cellSize))

            // check the cells above (and equal row)
            // these have object indices that are less than or equal to object1 cell's object indices
            // when we compare the two objects may actually be in the same cell
            // in this case we take care to ensure that object2's index is less than object1's

{'fraction_non_alphanumeric': 0.08826169342774509, 'fraction_numerical': 0.007380073800738007, 'mean_word_length': 2.430721861101608, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 51, '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': '4558068', 'n_tokens_mistral': 2824, 'n_tokens_neox': 2657, 'n_words': 803}