<commit_before>#include "atomic.hh"

class filetable {
public:
  filetable() : ref_(1) {
    for(int fd = 0; fd < NOFILE; fd++)
      ofile_[fd] = nullptr;
  }

  filetable(const filetable &f) : ref_(1) {
    for(int fd = 0; fd < NOFILE; fd++) {
      if (f.ofile_[fd])
        ofile_[fd] = f.ofile_[fd]->dup();
      else
        ofile_[fd] = nullptr;
    }
  }
  
  ~filetable() {
    for(int fd = 0; fd < NOFILE; fd++){
      if (ofile_[fd]){
        ofile_[fd]->close();
        ofile_[fd] = 0;
      }
    }
  }

  struct file *getfile(int fd) {
    if (fd < 0 || fd >= NOFILE)
      return nullptr;

    return ofile_[fd];
  }

  int allocfd(struct file *f) {
    for (int fd = 0; fd < NOFILE; fd++){
      if (ofile_[fd] == nullptr){
        ofile_[fd] = f;
        return fd;
      }
    }
    
    return -1;
  }

  void close(int fd) {
    struct file *f = ofile_[fd];
    ofile_[fd] = nullptr;
    f->close();
  }

  void decref() {
    if (--ref_ == 0)
      delete this;
  }

  void incref() {
    ref_++;
  }

  NEW_DELETE_OPS(filetable)

private:
  struct file *ofile_[NOFILE];
  std::atomic<u64> ref_;
};<commit_msg>A thread-safe, but non-scalable, filetable<commit_after>#include "atomic.hh"

class filetable {
public:
  filetable() : ref_(1) {
    for(int fd = 0; fd < NOFILE; fd++)
      ofile_[fd] = nullptr;
    initlock(&lock_, "filetable", 0);
  }

  filetable(const filetable &f) : ref_(1) {
    for(int fd = 0; fd < NOFILE; fd++) {
      if (f.ofile_[fd])
        ofile_[fd] = f.ofile_[fd]->dup();
      else
        ofile_[fd] = nullptr;
    }
    initlock(&lock_, "filetable", 0);
  }
  
  ~filetable() {
    for(int fd = 0; fd < NOFILE; fd++){
      if (ofile_[fd]){
        ofile_[fd]->close();
        ofile_[fd] = 0;
      }
    }
    destroylock(&lock_);
  }

  file *getfile(int fd) {
    file *f;

    if (fd < 0 || fd >= NOFILE)
      return nullptr;
    acquire(&lock_);
    f = ofile_[fd];
    // XXX(sbw) f->inc();
    release(&lock_);
    return f;
  }

  int allocfd(struct file *f) {
    acquire(&lock_);
    for (int fd = 0; fd < NOFILE; fd++) {
      if (ofile_[fd] == nullptr){
        ofile_[fd] = f;
        release(&lock_);
        return fd;
      }
    }
    release(&lock_);    
    return -1;
  }

  void close(int fd) {
    struct file *f = ofile_[fd];
    
    acquire(&lock_);
    ofile_[fd] = nullptr;
    release(&lock_);
    f->close();
  }

  void decref() {
    if (--ref_ == 0)
      delete this;
  }

  void incref() {
    ref_++;
  }

  NEW_DELETE_OPS(filetable)

private:
  struct file *ofile_[NOFILE];
  std::atomic<u64> ref_;
  struct spinlock lock_;
};
{'fraction_non_alphanumeric': 0.173414820473644, 'fraction_numerical': 0.009931245225362872, 'mean_word_length': 2.0848056537102475, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 14, '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': '617447', 'n_tokens_mistral': 1036, 'n_tokens_neox': 1004, 'n_words': 234}