ãã¡ã¤ã«ã®èªã¿æ¸ãããã«ãã¹ã¬ããã§ä¸¦åã«è¡ãããã®ä»çµã¿ããå種ããã°ã©ãã³ã°è¨èªï¼C++ãCãJavaãRubyãPythonï¼ã§å©ç¨ã§ããããã«ã©ã¤ãã©ãªãæ´åãããã¡ã¢ãªãããI/Oãé常I/Oããã¤ã¬ã¯ãI/Oãåãã¤ã³ã¿ã¼ãã§ã¤ã¹ã§å©ç¨ã§ãããTkrzw-0.9.38ãããã®æ©è½ãå©ç¨ã§ãããã¡ã¢ãªãããI/Oã¨é常I/Oã¯å ¨ã¦ã®å¦çç³»ã§ããã¤ã¬ã¯ãI/Oã¯Linuxã¨Macã¨Windowsã§å©ç¨ã§ããã
ãã¼ã¿ãã¼ã¹ã©ã¤ãã©ãªTkrzwã¯ãã«ãã¹ã¬ããç°å¢ã§ã®ä¸¦åå¦çæ§è½ãéè¦ãã¦éçºãã¦ããããããã§å©ç¨ãã¦ãããã¡ã¤ã«å±¤ã®æ©è½ãç´æ¥å©ç¨ã§ããããã«APIãæ´åããããã¼ã¿ãã¼ã¹ã¨ãã¦ã§ã¯ãªããåãªããã©ãããªãã¡ã¤ã«ã¨ãã¦å©ç¨ããããã®APIã§ãããããã¹ãã«ããã¤ããªã«ãå©ç¨ã§ããã
大åæã¨ãã¦ããã«ãã¹ã¬ããã§ä¸¦åã«èªã¿æ¸ããããã«ã¯ããã¡ã¤ã«ãªãã¸ã§ã¯ãããç¾å¨ä½ç½®ã¨ããæ¦å¿µãæ¨ã¦ãå¿ è¦ããããèªã¿æ¸ãããä½ç½®ãããã¡ã¤ã«å é ããã®ãªãã»ããã§æå®ãã¦ãèªã¿æ¸ããè¡ãå¿ è¦ããããä¾ãã°ããã¡ã¤ã«ã®101ãã¤ãç®ï¼å é ããã®ãªãã»ããã¯100ï¼ãã "hello" ã¨ãã5ãã¤ããæ¸ãè¾¼ã¿ãã¾ããããèªã¿åºãã«ã¯ãC++ã§ã¯ä»¥ä¸ã®ããã«ããã
file.Write(100, "hello", 5); char buf[5]; file.Read(100, buf, 5);
ãã®ã¹ã¬ãããã©ã®ä½ç½®ãèªã¿æ¸ããããã®ãã¯ããã®ã¹ã¬ããã管çãã¹ãåé¡ã ã次ã®ã¬ã³ã¼ããèªãã«ã¯ã次ã®ã¬ã³ã¼ãã®ä½ç½®ãç¥ãå¿ è¦ããããããããã©ããã£ã¦ãããã¯ãã¡ã¤ã«èªä½ã¯ç¥ããªããã¬ã³ã¼ãã®ãµã¤ãºãä¸å®ã«ãã¦ãIDã¨ãµã¤ãºã®æãç®ã§å ´æãç¹å®ããåºå®é·ã¬ã³ã¼ãæ¹å¼ã§ãè¯ãããåã ã®ã¬ã³ã¼ãã«èªåã®é·ãã®æ å ±ãåãè¾¼ãå¯å¤é·ã¬ã³ã¼ãæ¹å¼ã§ãè¯ããæ«å°¾ã«æ¹è¡ãã¤ããããã¹ãã¯ãåè¡ãã¬ã³ã¼ãã§ããå¯å¤é·ã¬ã³ã¼ãã®ãªã¹ãã§ããã¨ã¿ãªããã
ç¹å®ã®ä½ç½®ã¨ããããã§ã¯ãªãããã®æç¹ã§ã®ãã¡ã¤ã«ã®æ«å°¾ã«æ¸ãè¾¼ããªãã°ãAppendã¨ããã¡ã½ãããç¨ãããé©å½ãªæååã¨æ¹è¡æåãé£ç¶ãã¦æ¸ãè¾¼ãã«ã¯ã以ä¸ã®ããã«ããã
file.Append("hello\n"); file.Append("thank you\n"); file.Append("good bye\n");
Appendã®å¼ã³åºãã¯ä¸¦åã«è¡ãããããã®éã«ã¯è¿½è¨ãããã¼ã¿ãæ··ãããªãããã«æä»å¶å¾¡ããªãããããã£ã¦ãã¡ã¿ãã¼ã¿ãçªå µã§åºåãã示ãå¯å¤é·ã¬ã³ã¼ãã®æ¸ãè¾¼ã¿ã並åã«è¡ããã¨ãã§ãããåã¬ã³ã¼ããæ«å°¾ã«æ¹è¡æåãä¼´ãæååã§ããå ´åãçµæçã«æ¹è¡åºåãã®ããã¹ãã並åã«æ§ç¯ãããã¨ãã§ããã
hello thank you good bye
æ¹è¡åºåãããã¹ãããgrepçãªæ¤ç´¢ãè¡ãã¦ã¼ãã£ãªãã£ãæä¾ããã¦ãããæååã®ä¸éä¸è´ãåæ¹ä¸è´ãå¾æ¹ä¸è´ãæ£è¦è¡¨ç¾ãæçç·¨éè·é¢ãæ¡ä»¶ã«ãããã¨ãã§ããããã¡ã¤ã«ã®å é ããæ«å°¾ã¾ã§ã¹ãã£ã³ããæç´ãªå¦çã ããã©ã¤ãã©ãªå ã®ãã¤ãã£ãã³ã¼ãã§å®è¡ãããã®ã§ãJava/Ruby/Pythonã§è©²å½ã®å¦çãå®è£ ããå ´åããã¯ããªãé«éã«å¦çãã§ãããä¾ãã°ã"tokyo" ã«æãç·¨éè·é¢ãè¿ã10è¡ãæãåºãã«ã¯ã以ä¸ã®ããã«ããã
std::string pattern = "tokyo"; std::vector<std::string> lines; file.Search("edit", pattern, &lines, 10);
APIã®å
¨ã¦ã®æ©è½ã説æããã®ã¯é¢åãªã®ã§ãã¯ãã¯ããã¯çã«ãé¢ç½ã使ãæ¹ã«çµã£ã¦ç´¹ä»ãã¦ãããã以å¾ãã³ã¼ãä¾ã¯Rubyã§è¨è¿°ããããC++ã§ãCã§ãJavaã§ãPythonã§ãåããããªæ¸ãæ¹ãã§ããããã«ãªã£ã¦ããã
ã¾ãã¯ãæ¹è¡åºåãã§æååããã¡ã¤ã«ã«æ¸ãè¾¼ãã§ã¿ããopenã®ç¬¬1å¼æ°ã¯ãã¡ã¤ã«åã§ã第2å¼æ°ã¯æ¸ãè¾¼ã¿å¯è½ãã©ããã§ã第3å¼æ°ä»¥éã¯ãªãã·ã§ã³ãã©ã°ã ãtruncateã«trueãæå®ããã¨ããã¡ã¤ã«ã«æ¢åã®å 容ããã£ãå ´åã«ç©ºã«åæåãã¦ããããopenããã®ä»å¤ãã®ã¡ã½ããã¯Statusãªãã¸ã§ã¯ããè¿ãã®ã ãããã®or_dieã¡ã½ãããå¼ã¶ã¨ãå¦çã失æã§ãã£ãå ´åã«ä¾å¤ãæãã¦ãããã
require 'tkrzw' file = Tkrzw::File.new file.open("data.txt", true, truncate: true).or_die file.append("melon\n") file.append("apple\n") file.append("international\n") file.close.or_die
ã¡ã¢ãªãããI/Oã§ããã¹ããã¡ã¤ã«ã®ãã¼ã¿ãèªã¿è¾¼ãã§ãæ£è¦è¡¨ç¾ã«ããããã100è¡ãæãåºãã«ã¯ä»¥ä¸ã®ããã«ãããgrepã®mmapã¢ã¼ããAPIã§ä½¿ãããããªãã®ã ã
file.open("data.txt", false, concurrent: true).or_die p file.search("regex", "national$", 100) file.close.or_die
ãªããconcurrent: true ã¨ãããªãã·ã§ã³ãopenã¡ã½ããã«ä»ãããã¨ã§ãRubyã¤ã³ã¿ã¼ããªã¿ã®ã°ãã¼ãã«ããã¯ã解é¤ããç¶æ ã§å ¥åºåå¦çãè¡ãããããã«ãªãããã«ãã¹ã¬ããã§å¤§ããªãã¡ã¤ã«ãæ±ãå ´åããã®ãªãã·ã§ã³ãæå®ããã¨ã¹ã«ã¼ããããåä¸ãããPythonãåæ§ã«ã°ãã¼ãã«ããã¯ã使ãã¿ã¤ãã®å¦çç³»ãªã®ã§ãOpenã¡ã½ããã«concurret=Trueãä»ããã¨ã¹ã«ã¼ããããåä¸ããå ´åããããC++ãJavaã§ã¯å¦çç³»ã®ããã¯ã«ã¤ãã¦æ°ã«ããå¿ è¦ã¯ãªãã
ç·¨éè·é¢ãè¿ããã®ãåãåºããããªãã以ä¸ã®ããã«ãããããã¯agrepï¼å¤åambiguous grepã®ç¥ï¼ã®æ©è½ãAPIã§å©ç¨ããã®ã¨åãã ã
file.open("data.txt", false, concurrent: true).or_die p file.search("edit", "tokyo", 100) file.close.or_die
ããã©ã«ãã§ã¯mmapã使ã£ãã¡ã¢ãªãããI/Oãè¡ãããread/writeã使ã£ãé常I/Oã«åãæ¿ãããã¨ãã§ããããã¡ã¤ã«ãããªã大ããå ´åã«ã¯ããã¡ãã使ãã®ãè¯ãã
file.open("data.txt", false, concurrent: true, file: "pos-para").or_die p file.search("edit", "tokyo", 100) file.close.or_die
å®ã¡ã¢ãªã®æè¼éã¨ã¯æ¯è¼ã«ãªããªãã»ã©å¤§ãããã¡ã¤ã«ã®èªã¿æ¸ããæ³å®ããããä¾ãã°ã128ãã¤ãã®åºå®é·ã®ã¬ã³ã¼ãã10ååæ¸ãè¾¼ãã 120GBãããã®ãã¡ã¤ã«ãããã¨ãããããã®ãããªãã¡ã¤ã«ãèªã¿æ¸ãããå ´åããã¤ã¬ã¯ãI/Oã使ãæ¹ããããå ¥åºåã®ãã¼ã¿ããã¡ã¤ã«ã·ã¹ãã ã®ãã£ãã·ã¥ã«ä¹ããã¨ãã·ã¹ãã å ¨ä½ã®ã¡ã¢ãªãæ¯æ¸ããããã ã
ãã¤ã¬ã¯ãI/Oãå©ç¨ããã«ã¯ããã¡ã¤ã«ã¯ã©ã¹ï¼fileï¼ãPositionalParallelFileï¼pos-paraï¼ãPositionalAtomicFileï¼pos-atomï¼ã§ããããããã¯ãµã¤ãºï¼block_sizeï¼ã512ã®åæ°ã§ããå¿ è¦ããããããã¦ãã¢ã¯ã»ã¹ãªãã·ã§ã³ï¼access_optionsï¼ã« "direct:padding:pagecache" ãæå®ãããdirectã¯ãã¤ã¬ã¯ãI/Oãæå¹åããpaddingã¯ãã¡ã¤ã«ãµã¤ãºããããã¯ãµã¤ãºã®åæ°ã«ãªãããã«çµäºæã«ããã£ã³ã°ãå ¥ãã¦ãããpagecacheã¯ããã»ã¹å ã®ãã¼ã¸ãã£ãã·ã¥ãæå¹åãã¦å¦çå¹çãåä¸ãããã
require 'tkrzw' # åºå®é·ã¬ã³ã¼ãã®å¹ RECORD_WIDTH = 128 # ã¬ã³ã¼ãIDã«è©²å½ãããã¼ã¿ãå°åãã def print_record(file, id) offset = id * RECORD_WIDTH data = file.read(offset, RECORD_WIDTH) if data == nil raise "not found" end printf("%d: %s\n", id, data.strip) end # IDãæå®ãã¦ã¬ã³ã¼ããæ¸ãè¾¼ã def set_record(file, id, data) if data.size > RECORD_WIDTH raise "too large record" end data += " " * (RECORD_WIDTH - data.size) offset = id * RECORD_WIDTH file.write(offset, data).or_die end # ãã¡ã¤ã«ãæ¸ãè¾¼ã¿ã¢ã¼ãã§éã # 並åã¢ã¼ãã§ãã¤ã¬ã¯ãI/Oãã§ããããã«ãªãã·ã§ã³ãæå® file = Tkrzw::File.new file.open("fix-128.dat", true, concurrent: true, truncate: true, file: "pos-para", block_size: 512, access_options: "direct:padding:pagecache").or_die() # ã¬ã³ã¼ããæ¸ãè¾¼ã set_record(file, 1, "hydrogen") set_record(file, 3, "lithium") set_record(file, 11, "natrium") # ã¬ã³ã¼ããå°åãã print_record(file, 1) print_record(file, 3) print_record(file, 11) # ãã¡ã¤ã«ãéãã file.close.or_die
ä¸è¿°ã®ä¾ã§ã¯åºå®é·ã¬ã³ã¼ãã®ã©ã³ãã ã¢ã¯ã»ã¹ãè¡ã£ã¦ããããèªåã§ãã¼ã¿æ§é ãå®ç¾©ããã°ãå¯å¤é·ã¬ã³ã¼ãã®ã·ã¼ã±ã³ã·ã£ã«ã¢ã¯ã»ã¹ãããã©ããã¼ãæ¯è¼çç°¡åã«å®è£ ã§ãããä¸éçã«Record I/Oã¨ãå¼ã°ãããã¤ã ãä»åã¯ãå é 4ãã¤ãã«èªèº«ã®ãµã¤ãºãæã¡ããã®å¾ã«ä»»æã®ãã¤ããªãã¤ãªããæ§é ãå®ç¾©ãããããããã¡ã¤ã«ã®å é ããåãã¦ãã£ã¦ãããã«ãããèªã¿åºãããã°ã©ã ãæ¸ãã¦ã¿ãã
require 'tkrzw' # å¯å¤é·ã¬ã³ã¼ãã追å ãã def add_record(file, data) packed = [data.size].pack("N") + data file.append(packed) end # å¯å¤é·ã¬ã³ã¼ããèªã¿è¾¼ã¿ããã®ãã¼ã¿ã¨ã次ã®ã¬ã³ã¼ãã®ãªãã»ãããè¿ã # ããã¬ã³ã¼ãããªããã°ãnilãè¿ã def read_record(file, off) if off >= file.get_size return [nil, nil] end size = file.read(off, 4).unpack("N")[0] data = file.read(off + 4, size) [data, off + 4 + size] end # ãã¡ã¤ã«ãæ¸ãè¾¼ã¿ã¢ã¼ãã§éã # 並åã¢ã¼ãã§ãã¤ã¬ã¯ãI/Oãã§ããããã«ãªãã·ã§ã³ãæå® file = Tkrzw::File.new file.open("data.rio", true, concurrent: true, truncate: true, file: "pos-para", block_size: 512, access_options: "direct:padding:pagecache").or_die() # ã¬ã³ã¼ãã追å ãã ["hop", "step", "jump"].each { |record| add_record(file, record) } # ã¬ã³ã¼ããå é ããæ«å°¾ã¾ã§èªã¿è¾¼ãã§å°åãã off = 0 while true do data, off = read_record(file, off) break unless off p data end # ãã¡ã¤ã«ãéãã file.close().or_die()
å¯å¤é·ã¬ã³ã¼ãã®ã©ã³ãã ã¢ã¯ã»ã¹ããããå ´åãå¥éã¤ã³ããã¯ã¹ãä½ãå¿ è¦ããããappendã¡ã½ããã¯ããã®æã«ä¿åããã¬ã³ã¼ãã®å é ã®ãªãã»ãããè¿ãã®ã§ããã®ãªãã»ãããå¥ãã¡ã¤ã«ã«è¿½è¨ããã°ããããã¤ã³ããã¯ã¹ã¨ãã¦æ©è½ããããã«ãªãããªãã»ãããåºå®é·ã§è¡¨ç¾ããã°IDã¨ã®æãç®ã§æ¤ç´¢ã§ãããããã¼ã¨ãªãã»ããã®ãã¢ãæååã¨ãã¦ä¿åããã°ãsearchã¡ã½ããã§æ¤ç´¢ã§ããããã«ãªããã¨ã¯ãããããã¾ã§è¤éåãããªããããDBMã使ã£ãã»ããããã
ã¨ããã§ã ãã«ãã¹ã¬ããã«ãã並åã®Appendã®å¼ã³åºãã§ã¯æä»å¶å¾¡ããªãããã¨æ¸ããããããã¯ã©ããã£ã¦å®ç¾ããã¦ããã®ãã Appendãå¼ã³åºãããã¨ãæ¸ãè¾¼ããã¼ã¿ã®ãµã¤ãºã®åã ãããã¡ã¤ã«ãµã¤ãºã®ã¡ã¿ãã¼ã¿ãã¢ãããã¯ã«æ´æ°ãããã Appendãå¦çä¸ã®ã¹ã¬ããã ãããæ´æ°åã®ãã¡ã¤ã«ãµã¤ãºãå¾ããã¨ã«ãªãã®ã§ãããããªãã»ããã¨ãã¦æ¸ãè¾¼ã¿ãè¡ãã°ãç°ãªãã¹ã¬ãããåãé åã«æ¸ãè¾¼ã¿ãè¡ããã¨ã¯ãªãããä¸é£ã®ãã¼ã¿ãé£ç¶ããé åã«æ¸ãè¾¼ã¾ãããã¨ãä¿è¨¼ããããããããããã¯ããªã¼ãªä¸¦åæ¸ãè¾¼ã¿ãå®ç¾ã§ãã¦ããã
ã¡ã¿ãã¼ã¿ã®æ´æ°ã¯ã¢ãããã¯ã«è¡ããããããã¼ã¿ã®èªã¿æ¸ããã¢ãããã¯ã«è¡ããããã©ããã¯ããã¡ã¤ã«ã¯ã©ã¹ã«ä¾åãããããã©ã«ãã®ãã¡ã¤ã«ã¯ã©ã¹ï¼ MemoryMapParallelFile ) ã¯ãèªã¿æ¸ãèªä½ã«ã¯ããã¯ããããªãããããã£ã¦ãWriteãAppendããã¦ããæä¸ã®é åãReadãããã¨ãã§ããããã®éã«ã¯ãæ´æ°ä¸ã®ãã¼ã¿ãèªã¿è¾¼ã¾ãããã¤ã¾ããååã¯æ´æ°åã§å¾åã¯æ´æ°å¾ã¨ããç¶æ ã®ãã¼ã¿ãèªã¿è¾¼ã¾ããå¯è½æ§ãããããããå«ãªå ´åã¯ãå¼ã³åºãå´ãèªåã§æä»å¶å¾¡ãè¡ããã¨ã«ãªãï¼DBM層ã§ã¯ãããè¡ãªã£ã¦ããï¼ãPositionalParallelFileã¯ã©ã¹ã¯ãé常I/Oã¾ãã¯ãã¤ã¬ã¯ãI/Oã§ãåæ§ã®ä¸¦åæ§ã®èªã¿æ¸ããè¡ãã
ä¸æ¹ã§ãMemoryMapAtomicFileã¨PositionalAtomicFileã¯ã©ã¹ã¯ãReadã«ã¯ãã¡ã¤ã«å ¨ä½ã®ãªã¼ãããã¯ããWriteã¨Appendã«ã¯ãã¡ã¤ã«å ¨ä½ã®ã©ã¤ã¿ããã¯ããããããã£ã¦ãã©ããã®é åã«æ¸ãè¾¼ã¿ãè¡ã£ã¦ããã¹ã¬ãããããç¶æ ã§ã¯ãä»ã®ã¹ã¬ããã«ããæ¸ãè¾¼ã¿ã¨èªã¿è¾¼ã¿ã¯ãããã¯ããããèªã¿è¾¼ã¿å士ã¯ä¸¦åã«è¡ãããããããã£ã¦ãæ´æ°éä¸ã®ãã¼ã¿ãèªã¿è¾¼ã¾ããã¨ãããã¨ã¯ãªããªãããæ¸ãè¾¼ã¿å¦çãå¤ãå ´åã«ã¯ä¸¦åæ§ãèããä¸ããããã£ã¦ãã¢ããªã±ã¼ã·ã§ã³ã®ä¸¦åè¨è¨ã«ãã£ã¦ãé©åãªã¯ã©ã¹ãé¸æãããã¨ãèè¦ã ããã«ãã¹ã¬ããã使ããªãå ´åã«ã¯ããã¯ããããæå³ã¯ãªãã®ã§ã MemoryMapParallelFileãPositionalParallelFileã使ãã¹ãã ã
ã¾ã¨ããã¡ã¢ãªãããI/Oããã¤ã¬ã¯ãI/Oãã移æ¤å¯è½ãªæ¹æ³ã§è¡ãã®ã¯å¤§å¤ã ãããããTkrzwãå¦çç³»ã®éããå¸åãã¦ãããã®ã§ãJavaãPythonãRubyããã§ãç°¡åã«ãããã®æ©è½ãå©ç¨ãããã¨ãã§ããããã«ãã¹ã¬ããã使ãå ´åã«ã¯æä»å¶å¾¡ãããªãé¢åãªè¦ç´ ã«ãªã£ã¦ããã®ã ãããã®ããããã©ã¤ãã©ãªå ã§ãã¾ããã¨é è½ãã¦ãããã®ã§ãããã°ã©ãã³ã°ãæ°æ¥½ã«ãªãã並åã«èªã¿æ¸ãã§ãããã¡ã¤ã«ããã£ã¦åãã¦ã並åã«èªã¿æ¸ãã§ãããã¼ã¿ãã¼ã¹ããªãã¸ããªçãªæ©è½ãå®è£ ã§ããããã«ãªãã