<commit_before>// Copyright 2010-2013 RethinkDB, all rights reserved.
#ifndef CONTAINERS_SEGMENTED_VECTOR_HPP_
#define CONTAINERS_SEGMENTED_VECTOR_HPP_

#include <stdio.h>

#include "errors.hpp"

template <class element_t>
class segmented_vector_t {
private:
    static const size_t ELEMENTS_PER_SEGMENT = 1 << 14;

    struct segment_t {
        element_t elements[ELEMENTS_PER_SEGMENT];
    };

    std::vector<segment_t *> segments_;
    size_t size_;

public:
    explicit segmented_vector_t(size_t size = 0) : size_(0) {
        set_size(size);
    }

    ~segmented_vector_t() {
        set_size(0);
    }

public:
    element_t &operator[](size_t i) {
        return get(i);
    }

    const element_t &operator[](size_t i) const {
        return const_get(i);
    }

    element_t &get(size_t i) {
        return const_cast<element_t &>(const_get(i));
    }

    size_t size() const {
        return size_;
    }

    bool empty() const {
        return size_ == 0;
    }

    void push_back(const element_t &element) {
        size_t old_size = size_;
        set_size(old_size + 1);
        get(old_size) = element;
    }

    element_t &back() {
        guarantee(size_ > 0);
        return get(size_ - 1);
    }

    void pop_back() {
        guarantee(size_ > 0);
        set_size(size_ - 1);
    }

    // Note: sometimes elements will be initialized before you ask the
    // array to grow to that size (e.g. one hundred elements might be
    // initialized even though the array might be of size 1).
    void set_size(size_t new_size) {
        {
            const size_t num_segs = size_ != 0 ? ((size_ - 1) / ELEMENTS_PER_SEGMENT) + 1 : 0;
            guarantee(num_segs == segments_.size());
        }
        const size_t new_num_segs = new_size != 0 ? ((new_size - 1) / ELEMENTS_PER_SEGMENT) + 1 : 0;

        while (segments_.size() > new_num_segs) {
            delete segments_.back();
            segments_.pop_back();
        }
        while (segments_.size() < new_num_segs) {
            segments_.push_back(new segment_t);
        }

        size_ = new_size;
    }

    // This form of set_size fills the newly allocated space with a value
    void set_size(size_t new_size, element_t fill) {
        size_t old_size = size_;
        set_size(new_size);
        for (; old_size < new_size; old_size++) (*this)[old_size] = fill;
    }

private:
    const element_t &const_get(size_t i) const {
        rassert(i < size_, "i is %zu, size is %zu", i, size_);

        segment_t *segment = segments_[i / ELEMENTS_PER_SEGMENT];
        rassert(segment != NULL);
        return segment->elements[i % ELEMENTS_PER_SEGMENT];
    }

    DISABLE_COPYING(segmented_vector_t);<commit_msg>Removed unused functions from segmented_vector_t, slimming it down a bit.<commit_after>// Copyright 2010-2013 RethinkDB, all rights reserved.
#ifndef CONTAINERS_SEGMENTED_VECTOR_HPP_
#define CONTAINERS_SEGMENTED_VECTOR_HPP_

#include <stdio.h>

#include "errors.hpp"

template <class element_t>
class segmented_vector_t {
private:
    static const size_t ELEMENTS_PER_SEGMENT = 1 << 14;

    struct segment_t {
        element_t elements[ELEMENTS_PER_SEGMENT];
    };

    std::vector<segment_t *> segments_;
    size_t size_;

public:
    explicit segmented_vector_t(size_t size = 0) : size_(0) {
        set_size(size);
    }

    ~segmented_vector_t() {
        set_size(0);
    }

public:
    size_t size() const {
        return size_;
    }

    bool empty() const {
        return size_ == 0;
    }

    element_t &operator[](size_t index) {
        guarantee(index < size_, "index = %zu, size_ = %zu", index, size_);
        segment_t *seg = segments_[index / ELEMENTS_PER_SEGMENT];
        return seg->elements[index % ELEMENTS_PER_SEGMENT];
    }

    void push_back(const element_t &element) {
        size_t old_size = size_;
        set_size(old_size + 1);
        (*this)[old_size] = element;
    }

    element_t &back() {
        return (*this)[size_ - 1];
    }

    void pop_back() {
        guarantee(size_ > 0);
        set_size(size_ - 1);
    }

private:
    // Note: sometimes elements will be initialized before you ask the
    // array to grow to that size (e.g. one hundred elements might be
    // initialized even though the array might be of size 1).
    void set_size(size_t new_size) {
        {
            const size_t num_segs = size_ != 0 ? ((size_ - 1) / ELEMENTS_PER_SEGMENT) + 1 : 0;
            guarantee(num_segs == segments_.size());
        }
        const size_t new_num_segs = new_size != 0 ? ((new_size - 1) / ELEMENTS_PER_SEGMENT) + 1 : 0;

        while (segments_.size() > new_num_segs) {
            delete segments_.back();
            segments_.pop_back();
        }
        while (segments_.size() < new_num_segs) {
            segments_.push_back(new segment_t);
        }

        size_ = new_size;
    }

    DISABLE_COPYING(segmented_vector_t);
{'fraction_non_alphanumeric': 0.1072156543008561, 'fraction_numerical': 0.011618426416632695, 'mean_word_length': 2.4314685314685316, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 17, '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': '4210634', 'n_tokens_mistral': 1733, 'n_tokens_neox': 1655, 'n_words': 397}