fn add()

in Rust/src/pointstore.rs [203:277]


    fn add(&mut self, point: &[f32]) -> usize {
        let base = self.dimensions / self.shingle_size;
        self.next_sequence_index += 1;
        if self.internal_shingling {
            if point.len() != base {
                println!("The point must be '{}' floats long", self.dimensions);
                panic!();
            }
            for i in 0..(self.dimensions - base) {
                self.last_known_shingle[i] = self.last_known_shingle[i + base];
            }
            for i in 0..base {
                self.last_known_shingle[self.dimensions - base + i] = point[i];
            }
            if self.next_sequence_index < self.shingle_size {
                return usize::MAX;
            }
        } else if point.len() != self.dimensions {
            println!("The point must be '{}' floats long", self.dimensions);
            panic!();
        }

        if self.dimensions + self.start_free_region > self.store.len() {
            self.compact();
            if self.dimensions + self.start_free_region > self.store.len() {
                let mut new_size = self.store.len() + self.store.len() / 5;
                if new_size > self.capacity * self.dimensions {
                    new_size = self.capacity * self.dimensions;
                }
                self.store.resize(new_size, 0.0);
            }
        }

        if self.index_manager.is_empty() {
            assert!(self.reference_count.len() == self.location.len());
            let mut new_size = self.location.len() + self.location.len() / 5;
            if new_size > self.capacity {
                new_size = self.capacity;
            }
            self.location.resize(new_size, L::MAX);
            self.reference_count.resize(new_size, 0);
            self.index_manager.change_capacity(new_size);
        }
        let position: usize = self.index_manager.get();
        assert!(self.reference_count[position] == 0);
        self.reference_count[position] = 1;
        let new_point: &[f32] = if self.internal_shingling {
            &self.last_known_shingle
        } else {
            &point
        };

        if self.ready_to_copy(&new_point) {
            let base = self.dimensions / self.shingle_size;
            let mut index: usize = self.start_free_region;
            let extra = self.dimensions - base;
            let idx_value: usize = (index - extra) / base;
            self.location[position] = idx_value.try_into().unwrap();
            for i in 0..base {
                self.store[index] = new_point[extra + i];
                index += 1;
            }
            self.start_free_region += base;
        } else {
            let mut index: usize = self.start_free_region;
            let idx_value: usize = index / base;
            self.location[position] = idx_value.try_into().unwrap();
            for i in 0..self.dimensions {
                self.store[index] = new_point[i];
                index += 1;
            }
            self.start_free_region += self.dimensions;
        }
        position
    }