久々にBukkitプラグイン作りてえなぁってことで色々遡ってたら、以前とある人にgetConfig()を毎回使うとかディスクアクセス多すぎてファイル崩壊するんとちゃう?みたいなことを言われてたのを思い出して、確認してみた。
まずコレ見ると、初callでreloadConfig() (参照して遡ってもらえればわかるがFileConfigurationをディスクアクセスして作ってる)を呼び出し、以降はノンディスクアクセス。
んじゃぁFileConfiguration型のnewConfigがディスクアクセスしているのかわからないので、みてみる。
FileConfigurationはディスクアクセスしそうな関数を持たず、MemoryConfigurationを継承しているので遡る。
MemoryConfigurationも同様で、MemorySectionを継承。
MemorySectionをみてみた。
getKeys()メソッドでConfigurationオブジェクトっぽいのは、rootで、そいつはgetRoot()で呼び出されみてみると、
つまりMemorySectionでやってるってことかと再確認する。うん…?みてみてもちょっと複雑で疲れたし。まぁみた感じメモリにアクセスしてやってるっぽそうだし…。
なんてことは言えないので、違う方法でみてみた。
そういや、reloadConfig()メソッドってどうやって作ってるのかなぁって思ってみてみた。
YamlConfigurationでごちゃごちゃしてるみたい。
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/raw/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java?at=refs%2Fheads%2Fmaster を確認。
loadConfiguration(File file)メソッドは、YamlConfigurationのload(file)をcallしてるみたいなので、みると、(ちょっと短くしてます)
まぁ疲れたのでここまで。
Bukkitというか大きな開発ってこういうふうに階層深くなってるんだなぁと思いました。
@Override
public FileConfiguration getConfig() {
if (newConfig == null) {
reloadConfig();
}
return newConfig;
}https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/plugin/java/JavaPlugin.javaまずコレ見ると、初callでreloadConfig() (参照して遡ってもらえればわかるがFileConfigurationをディスクアクセスして作ってる)を呼び出し、以降はノンディスクアクセス。
んじゃぁFileConfiguration型のnewConfigがディスクアクセスしているのかわからないので、みてみる。
FileConfigurationはディスクアクセスしそうな関数を持たず、MemoryConfigurationを継承しているので遡る。
MemoryConfigurationも同様で、MemorySectionを継承。
MemorySectionをみてみた。
getKeys()メソッドでConfigurationオブジェクトっぽいのは、rootで、そいつはgetRoot()で呼び出されみてみると、
public Configuration getRoot() {
return root;
}んじゃrootはどこからってことで、みるとコンストラクターで作られてる(?) protected MemorySection() {
if (!(this instanceof Configuration)) {
throw new IllegalStateException("Cannot construct a root MemorySection when not a Configuration");
}
this.path = "";
this.fullPath = "";
this.parent = null;
this.root = (Configuration) this;
}自分自身を、ConfigurationSection継承のConfigurationにキャストしてるっぽい。つまりMemorySectionでやってるってことかと再確認する。うん…?みてみてもちょっと複雑で疲れたし。まぁみた感じメモリにアクセスしてやってるっぽそうだし…。
なんてことは言えないので、違う方法でみてみた。
そういや、reloadConfig()メソッドってどうやって作ってるのかなぁって思ってみてみた。
YamlConfigurationでごちゃごちゃしてるみたい。
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/raw/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java?at=refs%2Fheads%2Fmaster を確認。
loadConfiguration(File file)メソッドは、YamlConfigurationのload(file)をcallしてるみたいなので、みると、(ちょっと短くしてます)
@Override
public void loadFromString(String contents) throws InvalidConfigurationException {
Validate.notNull(contents, "Contents cannot be null");
Map<?, ?> input;
input = (Map<?, ?>) yaml.load(contents);
if (input != null) {
convertMapsToSections(input, this);
}
}
protected void convertMapsToSections(Map<?, ?> input, ConfigurationSection section) {
for (Map.Entry<?, ?> entry : input.entrySet()) {
String key = entry.getKey().toString();
Object value = entry.getValue();
if (value instanceof Map) {
convertMapsToSections((Map<?, ?>) value, section.createSection(key));
} else {
section.set(key, value);
}
}
}MapにしてSectionにしてるっぽいのでsection(ConfigurationSection型)というわけで、ConfigurationSectionを遡るとMemorySectionに至るのでみると、 public void set(String path, Object value) {
Validate.notEmpty(path, "Cannot set to an empty path");
Configuration root = getRoot();
if (root == null) {
throw new IllegalStateException("Cannot use section without a root");
}
final char separator = root.options().pathSeparator();
// i1 is the leading (higher) index
// i2 is the trailing (lower) index
int i1 = -1, i2;
ConfigurationSection section = this;
while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) {
String node = path.substring(i2, i1);
ConfigurationSection subSection = section.getConfigurationSection(node);
if (subSection == null) {
if (value == null) {
// no need to create missing sub-sections if we want to remove the value:
return;
}
section = section.createSection(node);
} else {
section = subSection;
}
}
String key = path.substring(i2);
if (section == this) {
if (value == null) {
map.remove(key);
} else {
map.put(key, value);
}
} else {
section.set(key, value);
}
}面倒なので適当に、たぶんmapにputしてるのでこのMapはと、protected final Map<String, Object> map = new LinkedHashMap<String, Object>();らしいので、ここで保管しているっぽい。
まぁ疲れたのでここまで。
Bukkitというか大きな開発ってこういうふうに階層深くなってるんだなぁと思いました。