Effective C++ 第二章
項目5: 明示的宣言よりも auto を優先する
- auto で宣言することのメリット
- 複雑な型宣言の省略
template<typename It> void f(It b, It e) { while (b != e) { typename std::iterator_traits<It>::value_type cV = *b; // auto cV = *b; } }
auto deffLess = [](const std::unique_ptr<Widget>& p1, const std::unique_ptr<Widget>& p2) { return *p1 < *p2; } // C++14 auto deffLess = [](const auto& p1, const auto& p2) { return *p1 < *p2; }
C++11 で登場した std::function 型でもラムダ式は表現可能だが、以下の点で auto のほうが有利
- シンタックスが簡潔
- メモリ使用量が少ない
- 実行速度が早い
型のショートカットによる実行環境依存の問題を回避できる
std::vector<int> v; unsigned sv = v.size(); // v.size() の戻り値の型は、std::vector<int>::size_type 型は、実行環境によりサイズが異なる // Windows 32bit では、32bit // Windows 64bit では、64bit // 一方 unsigned は どちらも32bit
- 型宣言のミスによる不要なオブジェクトのコピー及び未定義動作を回避可能
std::unordered_map<std::string, int> m; // std::pair 型は std::pair<const std::string, int> が正解 // 型の不一致により、一時オブジェクトが生成され、ループ内の最後の処理で破棄される for(const std::pair<std::string, int> p : m) { ... }
- ただし、auto による型宣言にも落とし穴がある
- 統一初期化子で初期化した変数の型が std::initializer_list
になる - std::vector
型のコンテナに対して operator を実行すると、std::vector ::reference が戻されることによる未定義動作の発生
- 統一初期化子で初期化した変数の型が std::initializer_list
項目6: auto が期待と異なる型を推論する場面では ETII を用いる
- std::vector
に対する operator はコンテナ要素の参照を返さない - C++ ではビットの参照を認めていない
- std::vector
の operator[] は T& を返す関数 - bool& は返すことができないため、bool& のように振る舞うオブジェクトを返す
- それが、std::vector
::reference - これは Proxy Class の一例
- Proxy Class には使用者にプロキシを意識させるものとそうでないものがある
- 意識させるもの: スマートポインタ
- 意識させないもの: std::vector
::reference - これが auto との相性が悪い (ユーザに意識させないプロキシクラスは、ライフタイムを1文以内と想定している)
- つまり、ユーザに意識させないプロキシクラスに対する auto 宣言は避けるべき
- Proxy Class には使用者にプロキシを意識させるものとそうでないものがある
- これは Proxy Class の一例
struct Widget {}; std::vector<bool> features(const Widget& w) { std::vector<bool> v = { true, false, true, false, true }; return v; } TEST(std_bool, features) { Widget w; auto priorities = features(w)[4]; EXPECT_STREQ("std::__1::__bit_reference<std::__1::vector<bool, std::__1::allocator<bool> >, true>", boost::typeindex::type_id_with_cvr<decltype(priorities)>().pretty_name().c_str()); }
- std::vector
::referece が bool& の動作を模倣する技法はたくさんある - その一例が暗黙の型変換
bool priorities = features(w)[4];
- auto 自体が問題ではなく、推論してほしい型を推論しないことが問題
- よって目的の型への推論を強制すれば良い
- それが、ETII (Explicitly typed initializer idiom)
auto priorities = std::static_cast<bool>(features(w)[4]);
NeoVim + dein の導入
はじめに
Mac にドキュメントエディタとして neovim を、neovim のプラグインマネージャとして dein をインストールします。
環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.14.6 BuildVersion: 18G4032
1. neovim のインストール
homebrew で一発インストール
$ brew install nvim
Ref: Installing-Neovim
インストールの確認
$ nvim -version NVIM v0.4.3 Build type: Release LuaJIT 2.0.5 Compilation: /usr/local/Homebrew/Library/Homebrew/shims/mac/super/clang -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -DNDEBUG -DMIN_LOG_LEVEL=3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wstrict-prototypes -std=gnu99 -Wshadow -Wconversion -Wmissing-prototypes -Wimplicit-fallthrough -Wvla -fstack-protector-strong -fdiagnostics-color=auto -DINCLUDE_GENERATED_DECLARATIONS -D_GNU_SOURCE -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -I/tmp/neovim-20191107-13403-1or2rj3/neovim-0.4.3/build/config -I/tmp/neovim-20191107-13403-1or2rj3/neovim-0.4.3/src -I/usr/local/include -I/tmp/neovim-20191107-13403-1or2rj3/neovim-0.4.3/deps-build/include -I/usr/local/opt/gettext/include -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include -I/tmp/neovim-20191107-13403-1or2rj3/neovim-0.4.3/build/src/nvim/auto -I/tmp/neovim-20191107-13403-1or2rj3/neovim-0.4.3/build/include Compiled by brew@Mojave.local Features: +acl +iconv +tui See ":help feature-compile" システム vimrc: "$VIM/sysinit.vim" 省略時の $VIM: "/usr/local/Cellar/neovim/0.4.3/share/nvim" Run :checkhealth for more info
2. neovim の設定
~/.vimrc
ではなく、~/.config/nvim/init.vim
に設定を書きます。
Configuration nvim-configuration
Use
$XDG_CONFIG_HOME/nvim/init.vim
instead of.vimrc
for configuration.- Use
$XDG_CONFIG_HOME/nvim
instead of.vim
to store configuration files.- Use
$XDG_DATA_HOME/nvim/shada/main.shada
instead of.viminfo
for persistent session information. |shada|
Ref: https://neovim.io/doc/user/vim_diff.html#nvim-configuration
neovim は
XDG Base Directory Specification
を使用しているソフトウェアであるため、上記が設定ファイルの格納場所となります。
XDG_CONFIG_HOME
- ユーザー個別の設定が書き込まれるディレクトリ (/etc と類似)。
- デフォルトは $HOME/.config です。
- ~/.config/nvim ディレクトリの作成
$ mkdir ~/.config/nvim
- ~/.config/nvim/init.vim の作成
" Configuration colorscheme desert filetype plugin indent on syntax on syntax enable set termguicolors set tabstop=4 softtabstop=4 expandtab shiftwidth=4 smarttab set list set listchars=tab:»-,trail:-,eol:↲,extends:»,precedes:«,nbsp:% set number set autoindent set fenc=utf-8 set noswapfile set autoread set hidden set showcmd set cursorline set cursorcolumn set visualbell set showmatch set laststatus=2 set wildmode=list:longest set ignorecase set smartcase set incsearch set wrapscan "" FileType autocmd FileType python setl autoindent autocmd FileType python setl smartindent cinwords=if,elif,else,for,while,try,except,finally,def,class autocmd FileType python setl tabstop=8 expandtab shiftwidth=4 softtabstop=4 autocmd FileType r setl tabstop=4 expandtab shiftwidth=2 softtabstop=2 autocmd BufNewFile,BufRead *.gvy setfiletype groovy autocmd BufNewFile,BufRead *.ts setfiletype typescript autocmd BufNewFile,BufRead *.tsx,*.jsx setfiletype=typescript.tsx "" Map Leader let mapleader = "\<Space>" let maplocalleader = "\<Space>" "" Custom Key Mapping nnoremap ; : nnoremap : ; inoremap <silent> jj <ESC> nnoremap <Leader>o :CtrlP<CR> nnoremap <Leader>w :w<CR> vmap <Leader>y "+y vmap <Leader>d "+d nmap <Leader>p "+p nmap <Leader>P "+P vmap <Leader>p "+p vmap <Leader>P "+P nmap <Leader><Leader> V map <C-n> ;NERDTreeToggle<CR> nnoremap s <Nop> nnoremap sj <C-w>j nnoremap sk <C-w>k nnoremap sl <C-w>l nnoremap sh <C-w>h nnoremap sJ <C-w>J nnoremap sK <C-w>K nnoremap sL <C-w>L nnoremap sH <C-w>H nnoremap sn gt nnoremap sp gT nnoremap sr <C-w>r nnoremap s= <C-w>= nnoremap sw <C-w>w nnoremap so <C-w>_<C-w>| nnoremap sO <C-w>= nnoremap sN :<C-u>bn<CR> nnoremap sP :<C-u>bp<CR> nnoremap st :<C-u>tabnew<CR> nnoremap sT :<C-u>Unite tab<CR> nnoremap ss :<C-u>sp<CR> nnoremap sv :<C-u>vs<CR> nnoremap sq :<C-u>q<CR> nnoremap sQ :<C-u>bd<CR>
3. dein.vim のインストール
- 以下の通り簡単に導入できます。
$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.cache/dein
4. dein.vim の設定
- インストール後に表示される通り、以下の設定を
~/.config/nvim/init.vim
に追記します。
"dein Scripts----------------------------- if &compatible set nocompatible " Be iMproved endif " Required: set runtimepath+=~/.cache/dein/repos/github.com/Shougo/dein.vim " Required: if dein#load_state('~/.cache/dein') call dein#begin('~/.cache/dein') " Let dein manage dein " Required: call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim') " Required: call dein#end() call dein#save_state() endif " Required: filetype plugin indent on syntax enable " If you want to install not installed plugins on startup. "if dein#check_install() " call dein#install() "endif "End dein Scripts-------------------------
- plugin の設定ファイルを toml 形式で管理するための設定
if dein#load_state('~/.cache/dein') call dein#begin('~/.cache/dein') " Let dein manage dein " Required: call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim') + call dein#load_toml('~/.config/nvim/dein.toml') + call dein#load_toml('~/.config/nvim/dein_lazy.toml', { 'lazy': 1 }) " Required: call dein#end() call dein#save_state() endif
CSV で Vector プロパティをロードする
環境
Oracle Graph Server Shell 20.1.0 PGX server version: 19.4.0 type: SM PGX server API version: 3.6.0 PGQL version: 1.2
前提
- Pgx Server で
allow_local_filesystem
が true になっており、かつdatasource_dir_whitelist
に/opt/oracle/oradata
ディレクトリが指定されている
$ cat /etc/oracle/graph/pgx.conf { "allow_local_filesystem": true, "datasource_dir_whitelist": ["/opt/oracle/oradata"], ... }
- Pgx Server が稼働するサーバの
/opt/oracle/oradata
に/opt/oracle/oradata/sample.vertices.csv
と/opt/oracle/oradata/sample.edges.csv
が格納されている。
/opt/oracle/oradata/vector_props.vertices.csv
1,1;2;3,0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40;41;42;43;44;45;46;47;48;49;50;51;52;53;54;55;56;57;58;59;60;61;62;63;64;65;66;67;68;69;70;71;72;73;74;75;76;77;78;79;80;81;82;83;84;85;86;87;88;89;90;91;92;93;94;95;96;97;98;99,0.0;0.01;0.02;0.03;0.04;0.05;0.06;0.07;0.08;0.09;0.1;0.11;0.12;0.13;0.14;0.15;0.16;0.17;0.18;0.19;0.2;0.21;0.22;0.23;0.24;0.25;0.26;0.27;0.28;0.29;0.3;0.31;0.32;0.33;0.34;0.35;0.36;0.37;0.38;0.39;0.4;0.41;0.42;0.43;0.44;0.45;0.46;0.47;0.48;0.49;0.5;0.51;0.52;0.53;0.54;0.55;0.56;0.57;0.58;0.59;0.6;0.61;0.62;0.63;0.64;0.65;0.66;0.67;0.68;0.69;0.7;0.71;0.72;0.73;0.74;0.75;0.76;0.77;0.78;0.79;0.8;0.81;0.82;0.83;0.84;0.85;0.86;0.87;0.88;0.89;0.9;0.91;0.92;0.93;0.94;0.95;0.96;0.97;0.98;0.99,"hoge0;hoge1;hoge2;hoge3;hoge4;hoge5;hoge6;hoge7;hoge8;hoge9;hoge10;hoge11;hoge12;hoge13;hoge14;hoge15;hoge16;hoge17;hoge18;hoge19;hoge20;hoge21;hoge22;hoge23;hoge24;hoge25;hoge26;hoge27;hoge28;hoge29;hoge30;hoge31;hoge32;hoge33;hoge34;hoge35;hoge36;hoge37;hoge38;hoge39;hoge40;hoge41;hoge42;hoge43;hoge44;hoge45;hoge46;hoge47;hoge48;hoge49;hoge50;hoge51;hoge52;hoge53;hoge54;hoge55;hoge56;hoge57;hoge58;hoge59;hoge60;hoge61;hoge62;hoge63;hoge64;hoge65;hoge66;hoge67;hoge68;hoge69;hoge70;hoge71;hoge72;hoge73;hoge74;hoge75;hoge76;hoge77;hoge78;hoge79;hoge80;hoge81;hoge82;hoge83;hoge84;hoge85;hoge86;hoge87;hoge88;hoge89;hoge90;hoge91;hoge92;hoge93;hoge94;hoge95;hoge96;hoge97;hoge98;hoge99"
/opt/oracle/oradata/vector_props.edges.csv
1,2,1;2;3
CSV ファイルをロードする
var gcb = GraphConfigBuilder.forFileFormat(Format.CSV). addVertexUri("/opt/oracle/oradata/vector_props.vertices.csv"). addEdgeUri("/opt/oracle/oradata/vector_props.edges.csv") // Vector タイプの PropertyType. 第三引数で次元を指定 gcb.addVertexVectorProperty("vp_vector_int", PropertyType.INTEGER, 3) gcb.addVertexVectorProperty("vp_vector_long", PropertyType.LONG, 100) gcb.addVertexVectorProperty("vp_vector_double", PropertyType.DOUBLE, 100) gcb.addVertexVectorProperty("vp_vector_string", PropertyType.STRING, 100) gcb.addEdgeVectorProperty("ep_vector_int", PropertyType.INTEGER, 3) var g = session.readGraphWithProperties(gcb.build()) // Vector 型のプロパティの値の取り出し方 var vec_v_int_prop = g.getVertex(1).getProperty("vp_vector_int") // => vec_v_int_prop ==> PgxVect[type=integer,dimension=3] var vec_v_int = (oracle.pgx.common.util.vector.Vect<Integer>) (vec_v_int_prop) /* * | Warning: * | unchecked cast * | required: oracle.pgx.common.util.vector.Vect<java.lang.Integer> * | found: java.lang.Object * | var vec_v_int = (oracle.pgx.common.util.vector.Vect<Integer>) (vec_v_int_prop); * | ^--------------^ * vec_v_int ==> PgxVect[type=integer,dimension=3] */ vec_v_int.toArray() // $231 ==> Integer[3] { 1, 2, 3 } // String 型の vector は java.lang.NullPointerException が発生する g.getVertex(1).getProperty("vp_vector_string") /* * Exception java.util.concurrent.ExecutionException: java.lang.NullPointerException *| at CompletableFuture.reportGet (CompletableFuture.java:395) *| at CompletableFuture.get (CompletableFuture.java:1999) *| at PgxFuture.get (PgxFuture.java:99) *| at PgxEntity.getProperty (PgxEntity.java:280) *| at (#284:1) *| Caused by: java.lang.NullPointerException *| at PgxEntity.lambda$getPropertyAsync$1 (PgxEntity.java:191) *| at CompletableFuture$UniCompose.tryFire (CompletableFuture.java:1072) *| at CompletableFuture.postComplete (CompletableFuture.java:506) *| at CompletableFuture.complete (CompletableFuture.java:2073) *| at PgxFuture.completeWithResultOrException (PgxFuture.java:55) *| at CompletableFuture.uniWhenComplete (CompletableFuture.java:859) *| at CompletableFuture$UniWhenComplete.tryFire (CompletableFuture.java:837) *| at CompletableFuture.postComplete (CompletableFuture.java:506) *| at CompletableFuture.complete (CompletableFuture.java:2073) *| at PgxRemoteFuture.executeRequest (PgxRemoteFuture.java:107) *| at PgxRemoteFuture.lambda$fetchRemoteResultAsync$3 (PgxRemoteFuture.java:218) *| at ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128) *| at ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:628) *| at Thread.run (Thread.java:834) */
Graph Config Json からロードする方法
{ "format": "csv", "edge_props": [{ "type": "integer", "name": "ep_vector_int", "dimension": 3 }], "error_handling": {}, "vertex_id_type": "integer", "vertex_uris": ["/opt/oracle/oradata/vector_props.vertices.csv"], "attributes": {}, "edge_uris": ["/opt/oracle/oradata/vector_props.edges.csv"], "loading": {}, "vertex_props": [{ "type": "integer", "name": "vp_vector_int", "dimension": 3 }, { "type": "long", "name": "vp_vector_long", "dimension": 100 }, { "type": "double", "name": "vp_vector_double", "dimension": 100 }] }
- PGX Client を起動して、Graph をロードする
// Graph Config Json ファイルは PGX Client 側に配置されているものを読みにいく var g = session.readGraphWithProperties("/tmp/vector_props_csv.json")
ローカルにある CSV で Graph をロードする
環境
Oracle Graph Server Shell 20.1.0 PGX server version: 19.4.0 type: SM PGX server API version: 3.6.0 PGQL version: 1.2
前提
- Pgx Server で
allow_local_filesystem
が true になっており、かつdatasource_dir_whitelist
に/opt/oracle/oradata
ディレクトリが指定されている
$ cat /etc/oracle/graph/pgx.conf { "allow_local_filesystem": true, "datasource_dir_whitelist": ["/opt/oracle/oradata"], ... }
- Pgx Server が稼働するサーバの
/opt/oracle/oradata
に/opt/oracle/oradata/sample.vertices.csv
と/opt/oracle/oradata/sample.edges.csv
が格納されている。
/opt/oracle/oradata/sample.vertices.csv
1,VL,0.1,1,1,true,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.1,"hoge",2,4 2,VL,-2.0,2,100000000000000000,false,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.2,"hage",3,1 3,VL,0.3,-3,-2222222222222222,false,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.3,"hige",4,4 4,VL,4.56789,3,-3333333333333,true,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.4,"huga",1,2
/opt/oracle/oradata/sample.edges.csv
1,2,EL,0.1,1,1,true,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.1,"hoge",2,4 2,1,EL,-2.0,2,100000000000000000,false,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.2,"hage",3,1 2,3,EL,0.3,-3,-2222222222222222,false,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.3,"hige",4,4 4,2,EL,4.56789,3,-3333333333333,true,2020-04-20,23:59:59.000000059,2020-04-20T16:46:40.000000300,2020-11-11T01:01:01.000000001+09:00,23:30:30.000000030+09:00,0.4,"huga",1,2
CSV ファイルをロードする
var gcb = GraphConfigBuilder.forFileFormat(Format.CSV). addVertexUri("/opt/oracle/oradata/sample.vertices.csv"). addEdgeUri("/opt/oracle/oradata/sample.edges.csv"). setVertexIdType(IdType.INTEGER). setTimeFormat(Arrays.asList("HH:mm:ss.SSSSSSSSS")). setTimeWithTimezoneFormat(Arrays.asList("HH:mm:ss.SSSSSSSSSXXX")). setTimestampFormat(Arrays.asList("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS")). setTimestampWithTimezoneFormat(Arrays.asList("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX")) // Vertex Properties gcb.addVertexProperty("vp_double", PropertyType.DOUBLE) gcb.addVertexProperty("vp_integer", PropertyType.INTEGER) gcb.addVertexProperty("vp_long", PropertyType.LONG) gcb.addVertexProperty("vp_boolean", PropertyType.BOOLEAN) gcb.addVertexProperty("vp_local_date",PropertyType.LOCAL_DATE) gcb.addVertexProperty("vp_time", PropertyType.TIME) gcb.addVertexProperty("vp_timestamp", PropertyType.TIMESTAMP) gcb.addVertexProperty("vp_timestamp_with_timezone", PropertyType.TIMESTAMP_WITH_TIMEZONE) gcb.addVertexProperty("vp_time_with_timezone", PropertyType.TIME_WITH_TIMEZONE) gcb.addVertexProperty("vp_float", PropertyType.FLOAT) gcb.addVertexProperty("vp_string", PropertyType.STRING) gcb.addVertexProperty("vp_vertex", PropertyType.VERTEX) gcb.addVertexProperty("vp_edge", PropertyType.EDGE) // Edge Properties gcb.addEdgeProperty("ep_double", PropertyType.DOUBLE) gcb.addEdgeProperty("ep_integer", PropertyType.INTEGER) gcb.addEdgeProperty("ep_long", PropertyType.LONG) gcb.addEdgeProperty("ep_boolean", PropertyType.BOOLEAN) gcb.addEdgeProperty("ep_local_date",PropertyType.LOCAL_DATE) gcb.addEdgeProperty("ep_time", PropertyType.TIME) gcb.addEdgeProperty("ep_timestamp", PropertyType.TIMESTAMP) gcb.addEdgeProperty("ep_timestamp_with_timezone", PropertyType.TIMESTAMP_WITH_TIMEZONE) gcb.addEdgeProperty("ep_time_with_timezone", PropertyType.TIME_WITH_TIMEZONE) gcb.addEdgeProperty("ep_float", PropertyType.FLOAT) gcb.addEdgeProperty("ep_string", PropertyType.STRING) gcb.addEdgeProperty("ep_vertex", PropertyType.VERTEX) gcb.addEdgeProperty("ep_edge", PropertyType.EDGE) // Label gcb.setLoadVertexLabels(true) gcb.setLoadEdgeLabel(true) var g = session.readGraphWithProperties(gcb.build())
Graph Config Json からロードする方法
{ "attributes": {}, "error_handling": {}, "timestamp_with_timezone_format": ["yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX"], "vertex_props": [{ "type": "double", "dimension": 0, "name": "vp_double" }, { "type": "integer", "dimension": 0, "name": "vp_integer" }, { "type": "long", "dimension": 0, "name": "vp_long" }, { "type": "boolean", "dimension": 0, "name": "vp_boolean" }, { "type": "local_date", "dimension": 0, "name": "vp_local_date" }, { "type": "time", "dimension": 0, "name": "vp_time" }, { "type": "timestamp", "dimension": 0, "name": "vp_timestamp" }, { "type": "timestamp_with_timezone", "dimension": 0, "name": "vp_timestamp_with_timezone" }, { "type": "time_with_timezone", "dimension": 0, "name": "vp_time_with_timezone" }, { "type": "float", "dimension": 0, "name": "vp_float" }, { "type": "string", "dimension": 0, "name": "vp_string" }, { "type": "vertex", "dimension": 0, "name": "vp_vertex" }, { "type": "edge", "dimension": 0, "name": "vp_edge" }], "format": "csv", "timestamp_format": ["yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS"], "time_format": ["HH:mm:ss.SSSSSSSSS"], "vertex_id_type": "integer", "loading": { "load_vertex_labels": true, "load_edge_label": true }, "vertex_uris": ["/opt/oracle/oradata/sample.vertices.csv"], "edge_props": [{ "type": "double", "dimension": 0, "name": "ep_double" }, { "type": "integer", "dimension": 0, "name": "ep_integer" }, { "type": "long", "dimension": 0, "name": "ep_long" }, { "type": "boolean", "dimension": 0, "name": "ep_boolean" }, { "type": "local_date", "dimension": 0, "name": "ep_local_date" }, { "type": "time", "dimension": 0, "name": "ep_time" }, { "type": "timestamp", "dimension": 0, "name": "ep_timestamp" }, { "type": "timestamp_with_timezone", "dimension": 0, "name": "ep_timestamp_with_timezone" }, { "type": "time_with_timezone", "dimension": 0, "name": "ep_time_with_timezone" }, { "type": "float", "dimension": 0, "name": "ep_float" }, { "type": "string", "dimension": 0, "name": "ep_string" }, { "type": "vertex", "dimension": 0, "name": "ep_vertex" }, { "type": "edge", "dimension": 0, "name": "ep_edge" }], "edge_uris": ["/opt/oracle/oradata/sample.edges.csv"], "time_with_timezone_format": ["HH:mm:ss.SSSSSSSSSXXX"] }
- PGX Client を起動して、Graph をロードする
// Graph Config Json ファイルは PGX Client 側に配置されているものを読みにいく var g = session.readGraphWithProperties("/tmp/sample_csv.json")
Vector プロパティをセットする方法
環境
Oracle Graph Server Shell 20.1.0 PGX server version: 19.4.0 type: SM PGX server API version: 3.6.0 PGQL version: 1.2
準備
- Graph の作成
var g = session.<Integer>newGraphBuilder(IdType.INTEGER).addVertex(1).build()
Vector プロパティの設定方法
- Vector Integer
// Vector Integer プロパティの作成 g.createVertexVectorProperty(PropertyType.INTEGER, 3 /* dimension */, "vp_vec_int") // Vector Integer プロパティのセット g.getVertex(1).setProperty("vp_vec_int", new oracle.pgx.api.PgxVect<Integer>(new Integer[]{1,2,3}))
- Vector Long
// Vector Long プロパティの作成 g.createVertexVectorProperty(PropertyType.LONG, 3 /* dimension */, "vp_vec_long") // Vector Long プロパティのセット g.getVertex(1).setProperty("vp_vec_long", new oracle.pgx.api.PgxVect<Long>(new Long[]{1L,2L,3L}))
- Vector Float
// Vector Float プロパティの作成 g.createVertexVectorProperty(PropertyType.FLOAT, 3 /* dimension */, "vp_vec_float") // Vector Float プロパティのセット g.getVertex(1).setProperty("vp_vec_float", new oracle.pgx.api.PgxVect<Float>(new Float[]{0.1f,0.2f,0.3f}))
- Vector Double
// Vector Double プロパティの作成 g.createVertexVectorProperty(PropertyType.DOUBLE, 3 /* dimension */, "vp_vec_double") // Vector Double プロパティのセット g.getVertex(1).setProperty("vp_vec_double", new oracle.pgx.api.PgxVect<Double>(new Double[]{0.1d,0.2d,0.3d}))
- Vector String プロパティのセットはできない
// Vector String プロパティの作成 g.createVertexVectorProperty(PropertyType.STRING, 3 /* dimension */, "vp_vec_string") // Vector String プロパティのセット -> エラー発生 g.getVertex(1).setProperty("vp_vec_string", new oracle.pgx.api.PgxVect<String>(new String[]{"str1", "str2", "str3})) | Exception java.lang.IllegalArgumentException: type string is not a valid vector property type | at PgxVect.<init> (PgxVect.java:49) | at (#23:1)
Vector プロパティの参照方法
- Vector Integer
((oracle.pgx.common.util.vector.Vect<Integer>)g.getVertex(1).getProperty("vp_vec_int")).toArray() | Warning: | unchecked cast | required: oracle.pgx.common.util.vector.Vect<java.lang.Integer> | found: java.lang.Object | ((oracle.pgx.common.util.vector.Vect<Integer>)g.getVertex(1).getProperty("vp_vec_int")).toArray() | ^--------------------------------------^ $28 ==> Integer[3] { 1, 2, 3 }
- Vector Long
((oracle.pgx.common.util.vector.Vect<Long>)g.getVertex(1).getProperty("vp_vec_long")).toArray() | Warning: | unchecked cast | required: oracle.pgx.common.util.vector.Vect<java.lang.Long> | found: java.lang.Object | ((oracle.pgx.common.util.vector.Vect<Long>)g.getVertex(1).getProperty("vp_vec_long")).toArray() | ^---------------------------------------^ $29 ==> Long[3] { 1, 2, 3 }
- Vector Double
((oracle.pgx.common.util.vector.Vect<Double>)g.getVertex(1).getProperty("vp_vec_double")).toArray() | Warning: | unchecked cast | required: oracle.pgx.common.util.vector.Vect<java.lang.Double> | found: java.lang.Object | ((oracle.pgx.common.util.vector.Vect<Double>)g.getVertex(1).getProperty("vp_vec_double")).toArray() | ^-----------------------------------------^ $30 ==> Double[3] { 0.1, 0.2, 0.3 }
- Vector Float
((oracle.pgx.common.util.vector.Vect<Float>)g.getVertex(1).getProperty("vp_vec_float")).toArray() | Warning: | unchecked cast | required: oracle.pgx.common.util.vector.Vect<java.lang.Float> | found: java.lang.Object | ((oracle.pgx.common.util.vector.Vect<Float>)g.getVertex(1).getProperty("vp_vec_float")).toArray() | ^----------------------------------------^ $31 ==> Float[3] { 0.1, 0.2, 0.3 }
Graph Server 20.1 で GraphConfig をbuildできない問題
setKeystoreAlias("alias") でbuildすればおけ
実践 Rust 入門 第4章プリミティブ型
Rust における型
- すべての値の型はコンパイル時に決定される
- これは安全性、効率性という利点がある
- 安全性: エラーの早期発見、所有権システムとの連携による型安全かつデータ競合のないプログラム開発の促進
- 効率性: メモリの細かい制御、コンパイラによる最適化の恩恵
- これは安全性、効率性という利点がある
型の分類
定義による分類
- プリミティブ型
- ユーザ定義型
構成による分類
- スカラ型
- 複合型
スカラ型
- ユニット
- 真理値
- 固定精度の整数
- 固定精度の浮動小数点
- 文字
- 参照
- 生ポインタ
- 関数ポイント
let n = 40; let c = 'R';
ユニット
- 値を返さない関数の戻り値はユニット型
- ユニット型は意味のある情報を持たないため、サイズは0
- キーバリューのペアを格納するデータ構造でキーのみデータを保持したい場合には、バリューにユニットを格納すると無駄にメモリを消費しない
assert_eq!(std::mem::size_of::<()>(), 0);
真偽値
- true と false を持つ
let b1 = true; let b2 = !b1; let n1 = 1; let n2 = 2; let b3 = n1 >= n2; let b4 = n1 < n2; let b5 = b3 && b4; let b6 = b3 || b4;
固定精度の整数
- ビット幅指定の整数型
- 符号なし (uxx)
- 符号あり (ixx)
let n1: i32 = 32;
- アドレス幅の整数型
- usize
- isize
let n2: usize = 32;
- 整数リテラル
- デフォルト10進数
- プレフィクスで他の基数に基づく数を表される
- 0x: 16進数
- 0o: 8進数
- 0b: 2進数
let h1 = 0xff; let o1 = 0o744; let b1 = 0b1010_0110_1110_1001;
- サフィックスで型を指定可能
let n1 = 10u8;
- ASCII 文字に対する文字コードを得ることも可能
let n2 = b'A'; assert_eq!(n2, 65u8);
代表的な整数演算
整数型のメソッドや定数
- 整数型のメソッド
- pow(), abs(), rotate_left(), from_str(), to_string(), checked_add()
- 定数
- 最大値 MAX 等
整数演算の桁あふれ
- リリースモードでは桁あふれは検出できない
- 以下の方法で対応するメソッドを使用することを検討する
- 検査付き演算
- 飽和演算
- ラッピング演算
- 桁あふれ演算
- 以下の方法で対応するメソッドを使用することを検討する
fn overflow_calc() { let n1 = 200u8; let n2 = 3u8; assert_eq!(n1.checked_mul(n2), None); assert_eq!(n1.saturating_mul(n2), std::u8::MAX); assert_eq!(n1.wrapping_mul(n2), 88); assert_eq!(n1.overflowing_mul(n2), (88, true)); }
固定精度の浮動小数点
- ビット数に応じてf32, f64の2つの型が用意されている
- サフィックスで型を指定可能
- 指数部も指定可能
let f1 = 10.0; let f2 = 1_234.897f64; let f3 = 576.6E77;
文字
- 1つのUnicodeのスカラ値
- シングルクォートで囲む
- 1文字を表すのにたとえ英数字であっても4バイトを消費する
- 複数のコードポイントが組み合わされた文字例えば'が'などは char リテラルとして使用することはできない(コンパイルエラー)
let c1 = 'A'; let c2 = 'B'; assert!(c1 <= c2); assert!(c1.is_uppercase()); let c3 = '0'; assert!(c3.is_digit(10)); let c4 = '\t'; let c5 = '\''; let c6 = '\\'; let c7 = '\x7F'; let c8 = '漢'; let c9 = '\u{5b57}'; let c10 = '\u{1f600}'; println!("{}", c10);
参照
- メモリ安全ポインタ
- データが格納されている場所を指す
- usize と同じビット幅の整数で表される
fn f1(mut n: u32){ n = 1; println!("{}", n); } fn f2(n_ptr: &mut u32){ println!("f2: n_ptr {:p}", n_ptr); *n_ptr = 2; println!("{}", n_ptr); } let mut f_n1 = 0; f1(f_n1); println!("{}", f_n1); f2(&mut f_n1); println!("{}", f_n1);
生ポインタ
- メモリ安全ではないポインタ
- dereference するときに unsafe ブロック内に処理を記述する必要性がある
let mut c1 = 'A'; let c1_ptr: *mut char = &mut c1; assert_eq!(unsafe{*c1_ptr}, 'A'); unsafe { *c1_ptr = 'B'; }
関数ポインタ
- 関数を指すポインタ
fn double(n: i32) -> i32 { n + n } fn abs(n: i32) -> i32 { if n >= 0 { n } else { -n } } let f1: fn(i32) -> i32 = double; let f2: fn(i32) -> i32 = abs; assert_eq!(std::mem::size_of_val(&f1), std::mem::size_of::<usize>()); let mut f3 = double; assert_eq!(std::mem::size_of_val(&f3), 0);