Java9のStringABuilder.appndの処理
Java9の変更点を調べていたら、ソースコードが見たくなってきたので、openjdkのソースコードを見てみた。
Stringに関しては以下のブログで紹介されています。
今回調べて見たのでは、StringBuilder.appendの処理。
LATIN1からUTF-16を追加するときの処理です。
ソースコード
StringBuilder
public StringBuilder append(String str) { super.append(str); return this; }
AbstractStringBuilder
public AbstractStringBuilder append(String str) { if (str == null) { return appendNull(); } int len = str.length(); ensureCapacityInternal(count + len); putStringAt(count, str); count += len; return this; }
ensureCapacityInternalで領域を確保して、putStringAtで結合しているようです。
ensureCapacityInternalに関しては、どのようなオーバーフローを気にしているのか?newCapacityにはどのようなサイズを取得しようとしているのかが、正直良くわからなかったです。
private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code int oldCapacity = value.length >> coder; if (minimumCapacity - oldCapacity > 0) { value = Arrays.copyOf(value, newCapacity(minimumCapacity) << coder); } }
private int newCapacity(int minCapacity) { // overflow-conscious code int oldCapacity = value.length >> coder; int newCapacity = (oldCapacity << 1) + 2; if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } int SAFE_BOUND = MAX_ARRAY_SIZE >> coder; return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity; }
そして本題はputStringAtです。
この中でcoderを比較して違っていたら拡張しています。
private final void putStringAt(int index, String str) { if (getCoder() != str.coder()) { inflate(); } str.getBytes(value, index, coder); }
ここで一文字ずつコピーしているのがわかります。
public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len) { // We need a range check here because 'putChar' has no checks checkBoundsOffCount(dstOff, len, dst); for (int i = 0; i < len; i++) { putChar(dst, dstOff++, src[srcOff++] & 0xff); } }
static void putChar(byte[] val, int index, int c) { assert index >= 0 && index < length(val) : "Trusted caller missed bounds check"; index <<= 1; val[index++] = (byte)(c >> HI_BYTE_SHIFT); val[index] = (byte)(c >> LO_BYTE_SHIFT); }
感想
綺麗なソースコードが読めて、学びはたくさんあるが、読むのは結構難しい。
mac book pro 設定その2
今回インストールしたのはdein.vimです。
dein.vimはneobundleらしいです。よく知らないですが。
インストール方法
$ mkdir -p ~/.cache/dein $ cd ~/.cache/dein $ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh $ sh ./installer.sh ~/.cache/dein
あとは表示されたスクリプトを~/.vimrcに記述してvimを起動するだけ。
ただし、ここで"deol.nvim requires Neovim"と表示される。
ググったところ、deol.nvimのrevを削除すればできるらしいのでrevを削除し、deol.nvimを削除しvimを再起動。
そしたら今度は"deol.nvim requires Neovim or terminal feature enabled Vim."と表示される。
ここでハマってしまったが、結果的には最新のvimをインストールすることで解決。
もともとデフォルトで入っていたバージョン。
$ vim --version VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jul 26 2017 19:10:24) Included patches: 1-503, 505-642 Compiled by root@apple.com
最新のものをbrewでインストール。
$ brew install vim $ vim --version VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Feb 13 2018 12:01:41) macOS version Included patches: 1-1500 Compiled by Homebrew
参考サイト
dein.vimのインストール自体にハマってしまったメモ
https://qiita.com/DialBird/items/0a96910f13586d635dc0