storage.h 4.1 KB
Newer Older
S
superjom 已提交
1 2
#ifndef VISUALDL_STORAGE_STORAGE_H
#define VISUALDL_STORAGE_STORAGE_H
S
superjom 已提交
3

S
superjom 已提交
4
#include <glog/logging.h>
S
superjom 已提交
5
#include <algorithm>
S
superjom 已提交
6
#include <set>
S
superjom 已提交
7
#include <vector>
S
superjom 已提交
8

S
superjom 已提交
9
#include "visualdl/logic/im.h"
S
superjom 已提交
10
#include "visualdl/storage/storage.pb.h"
S
superjom 已提交
11
#include "visualdl/storage/tablet.h"
S
superjom 已提交
12
#include "visualdl/utils/filesystem.h"
S
superjom 已提交
13
#include "visualdl/utils/guard.h"
S
superjom 已提交
14 15 16

namespace visualdl {

S
superjom 已提交
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
static const std::string meta_file_name = "storage.meta";

static std::string meta_path(const std::string& dir) {
  CHECK(!dir.empty()) << "dir is empty";
  return dir + "/" + meta_file_name;
}
static std::string tablet_path(const std::string& dir, const std::string& tag) {
  CHECK(!dir.empty()) << "dir should be set first";
  return dir + "/" + tag;
}

struct SimpleSyncMeta {
  void Inc() { counter++; }

  bool ToSync() { return counter % cycle == 0; }

  size_t counter{0};
  int cycle;
};

37
/*
S
superjom 已提交
38
 * Helper for operations on storage::Storage.
39
 */
S
superjom 已提交
40
struct Storage {
S
superjom 已提交
41 42 43 44
  DECL_GUARD(Storage)

  mutable SimpleSyncMeta meta;

S
superjom 已提交
45 46 47 48
  Storage() {
    data_ = std::make_shared<storage::Storage>();
    tablets_ = std::make_shared<std::map<std::string, storage::Tablet>>();
    modes_ = std::make_shared<std::set<std::string>>();
49 50
    time_t t;
    time(&t);
S
superjom 已提交
51
    data_->set_timestamp(t);
52
  }
S
superjom 已提交
53 54
  Storage(const Storage& other)
      : data_(other.data_), tablets_(other.tablets_), modes_(other.modes_) {}
55

S
superjom 已提交
56 57
  // write operations
  void AddMode(const std::string& x) {
S
superjom 已提交
58
    // avoid duplicate modes.
S
superjom 已提交
59
    if (modes_->count(x) != 0) return;
S
superjom 已提交
60
    *data_->add_modes() = x;
S
superjom 已提交
61
    modes_->insert(x);
S
superjom 已提交
62
    WRITE_GUARD
S
Superjom 已提交
63
  }
64

S
superjom 已提交
65
  Tablet AddTablet(const std::string& x) {
S
superjom 已提交
66 67
    CHECK(tablets_->count(x) == 0) << "tablet [" << x << "] has existed";
    (*tablets_)[x] = storage::Tablet();
S
superjom 已提交
68 69
    AddTag(x);
    LOG(INFO) << "really add tag " << x;
S
superjom 已提交
70 71 72
    // WRITE_GUARD
    PersistToDisk();
    return Tablet(&(*tablets_)[x], this);
S
superjom 已提交
73
  }
74

S
superjom 已提交
75 76 77 78 79 80
  void SetDir(const std::string& dir) { dir_ = dir; }
  void PersistToDisk() { PersistToDisk(dir_); }
  /*
   * Save memory to disk.
   */
  void PersistToDisk(const std::string& dir) {
S
superjom 已提交
81
    // LOG(INFO) << "persist to disk " << dir;
S
superjom 已提交
82 83 84 85 86
    CHECK(!dir.empty()) << "dir should be set.";
    fs::TryRecurMkdir(dir);

    fs::SerializeToFile(*data_, meta_path(dir));
    for (auto tag : data_->tags()) {
S
superjom 已提交
87 88
      auto it = tablets_->find(tag);
      CHECK(it != tablets_->end()) << "tag " << tag << " not exist.";
S
superjom 已提交
89 90 91 92 93 94
      fs::SerializeToFile(it->second, tablet_path(dir, tag));
    }
  }

  Storage* parent() { return this; }

S
superjom 已提交
95
protected:
S
superjom 已提交
96 97
  void AddTag(const std::string& x) {
    *data_->add_tags() = x;
S
superjom 已提交
98 99 100
    LOG(INFO) << "add tag " << x;
    LOG(INFO) << "tag.size " << data_->tags_size();
    WRITE_GUARD
S
superjom 已提交
101
  }
102

103
private:
S
superjom 已提交
104
  std::string dir_;
S
superjom 已提交
105
  std::shared_ptr<std::map<std::string, storage::Tablet>> tablets_;
S
superjom 已提交
106
  std::shared_ptr<storage::Storage> data_;
S
superjom 已提交
107
  std::shared_ptr<std::set<std::string>> modes_;
S
superjom 已提交
108 109 110 111 112 113 114 115 116
};

/*
 * Storage reader, each interface will trigger a read.
 */
struct StorageReader {
  StorageReader(const std::string& dir) : dir_(dir) {}

  // read operations
S
superjom 已提交
117
  std::vector<std::string> all_tags() {
S
superjom 已提交
118 119 120 121 122
    storage::Storage storage;
    Reload(storage);
    return std::vector<std::string>(storage.tags().begin(),
                                    storage.tags().end());
  }
S
superjom 已提交
123 124 125 126 127 128 129 130 131 132 133
  std::vector<std::string> tags(Tablet::Type component) {
    auto tags = all_tags();
    auto it =
        std::remove_if(tags.begin(), tags.end(), [&](const std::string& tag) {
          auto tb = tablet(tag);
          return tb.type() != component;
        });
    tags.resize(it - tags.begin());
    return tags;
  }
  std::vector<std::string> modes() {
S
superjom 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
    storage::Storage storage;
    Reload(storage);
    return std::vector<std::string>(storage.modes().begin(),
                                    storage.modes().end());
  }

  TabletReader tablet(const std::string& tag) const {
    auto path = tablet_path(dir_, tag);
    storage::Tablet tablet;
    fs::DeSerializeFromFile(&tablet, path);
    return TabletReader(tablet);
  }

protected:
  void Reload(storage::Storage& storage) {
    const std::string path = meta_path(dir_);
    fs::DeSerializeFromFile(&storage, path);
  }

private:
  std::string dir_;
155 156 157
};

}  // namespace visualdl
S
superjom 已提交
158

S
superjom 已提交
159
#endif