roma 0.8.2 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. data/CHANG +326 -0
  2. data/CHANGELOG +132 -0
  3. data/{README.rdoc → FETCH_HEAD} +0 -0
  4. data/{LICENSE.rdoc → LICENSE} +0 -1
  5. data/README +17 -0
  6. data/Rakefile +33 -18
  7. data/ruby/server/bin/chg_redundancy +10 -0
  8. data/ruby/server/bin/key_access +7 -0
  9. data/ruby/server/bin/key_list +7 -0
  10. data/ruby/server/bin/mkconfig +19 -0
  11. data/{bin → ruby/server/bin}/mkrecent +0 -1
  12. data/{bin → ruby/server/bin}/mkroute +0 -1
  13. data/ruby/server/bin/multi_commander +19 -0
  14. data/ruby/server/bin/recoverlost +10 -0
  15. data/ruby/server/bin/recoverlost_alist +10 -0
  16. data/ruby/server/bin/recoverlost_alist_all +10 -0
  17. data/ruby/server/bin/recoverlost_alist_keys +10 -0
  18. data/{bin/recoverlost → ruby/server/bin/roma_watcher} +1 -2
  19. data/ruby/server/bin/romad +36 -0
  20. data/{bin → ruby/server/bin}/sample_watcher +0 -1
  21. data/{bin → ruby/server/bin}/sample_watcher2 +0 -1
  22. data/{bin/simple_bench → ruby/server/bin/sample_watcher3} +1 -2
  23. data/ruby/server/bin/simple_bench +26 -0
  24. data/{bin → ruby/server/bin}/ssroute +0 -1
  25. data/ruby/server/bin/test-scenario +11 -0
  26. data/{bin → ruby/server/bin}/tribunus +0 -1
  27. data/{lib → ruby/server/lib}/roma/async_process.rb +67 -15
  28. data/{lib → ruby/server/lib}/roma/command/bg_command_receiver.rb +1 -1
  29. data/ruby/server/lib/roma/command/command_definition.rb +422 -0
  30. data/ruby/server/lib/roma/command/mh_command_receiver.rb +127 -0
  31. data/ruby/server/lib/roma/command/receiver.rb +64 -0
  32. data/{lib → ruby/server/lib}/roma/command/rt_command_receiver.rb +6 -1
  33. data/ruby/server/lib/roma/command/sys_command_receiver.rb +609 -0
  34. data/{lib → ruby/server/lib}/roma/command/util_command_receiver.rb +15 -5
  35. data/{lib → ruby/server/lib}/roma/command/vn_command_receiver.rb +12 -4
  36. data/{lib → ruby/server/lib}/roma/command_plugin.rb +0 -0
  37. data/ruby/server/lib/roma/config.rb +84 -0
  38. data/{lib → ruby/server/lib}/roma/event/con_pool.rb +12 -1
  39. data/ruby/server/lib/roma/event/handler.rb +256 -0
  40. data/ruby/server/lib/roma/live_patch-20120302-001.rb +107 -0
  41. data/ruby/server/lib/roma/logging/rlogger.rb +163 -0
  42. data/ruby/server/lib/roma/messaging/con_pool.rb +92 -0
  43. data/{lib → ruby/server/lib}/roma/plugin/plugin_alist.rb +118 -240
  44. data/ruby/server/lib/roma/plugin/plugin_debug.rb +31 -0
  45. data/ruby/server/lib/roma/plugin/plugin_map.rb +177 -0
  46. data/ruby/server/lib/roma/plugin/plugin_mapcount.rb +185 -0
  47. data/{lib/roma/command/st_command_receiver.rb → ruby/server/lib/roma/plugin/plugin_storage.rb} +170 -146
  48. data/ruby/server/lib/roma/plugin/plugin_stub.rb +283 -0
  49. data/{lib → ruby/server/lib}/roma/plugin/plugin_test.rb +0 -0
  50. data/{lib → ruby/server/lib}/roma/romad.rb +221 -94
  51. data/{lib → ruby/server/lib}/roma/routing/cb_rttable.rb +4 -6
  52. data/{lib → ruby/server/lib}/roma/routing/merkle_tree.rb +0 -0
  53. data/ruby/server/lib/roma/routing/routing_data.rb +307 -0
  54. data/{lib → ruby/server/lib}/roma/routing/rttable.rb +4 -0
  55. data/{lib → ruby/server/lib}/roma/stats.rb +19 -3
  56. data/{lib → ruby/server/lib}/roma/storage/basic_storage.rb +25 -26
  57. data/{lib → ruby/server/lib}/roma/storage/dbm_storage.rb +1 -23
  58. data/{lib → ruby/server/lib}/roma/storage/dummy_storage.rb +0 -0
  59. data/{lib → ruby/server/lib}/roma/storage/rh_storage.rb +0 -0
  60. data/{lib → ruby/server/lib}/roma/storage/sqlite3_storage.rb +0 -0
  61. data/{lib → ruby/server/lib}/roma/storage/tc_storage.rb +62 -2
  62. data/ruby/server/lib/roma/tools/chg_redundancy.rb +36 -0
  63. data/ruby/server/lib/roma/tools/key_access.rb +105 -0
  64. data/ruby/server/lib/roma/tools/key_list.rb +94 -0
  65. data/ruby/server/lib/roma/tools/mkconfig.rb +535 -0
  66. data/{lib → ruby/server/lib}/roma/tools/mkrecent.rb +0 -0
  67. data/{lib → ruby/server/lib}/roma/tools/mkroute.rb +0 -0
  68. data/ruby/server/lib/roma/tools/multi_commander.rb +45 -0
  69. data/{lib → ruby/server/lib}/roma/tools/recoverlost.rb +0 -0
  70. data/{lib → ruby/server/lib}/roma/tools/recoverlost_alist.rb +0 -0
  71. data/ruby/server/lib/roma/tools/recoverlost_alist_all.rb +8 -0
  72. data/ruby/server/lib/roma/tools/recoverlost_alist_keys.rb +16 -0
  73. data/ruby/server/lib/roma/tools/recoverlost_lib.rb +349 -0
  74. data/ruby/server/lib/roma/tools/roma_watcher.rb +150 -0
  75. data/ruby/server/lib/roma/tools/roma_watcher_config.yml.example +20 -0
  76. data/{lib → ruby/server/lib}/roma/tools/sample_watcher.rb +3 -1
  77. data/{lib → ruby/server/lib}/roma/tools/sample_watcher2.rb +3 -1
  78. data/ruby/server/lib/roma/tools/sample_watcher3.rb +49 -0
  79. data/{lib → ruby/server/lib}/roma/tools/simple_bench.rb +2 -0
  80. data/ruby/server/lib/roma/tools/simple_bench2.rb +78 -0
  81. data/{lib → ruby/server/lib}/roma/tools/ssroute.rb +0 -0
  82. data/ruby/server/lib/roma/tools/test-scenario.rb +327 -0
  83. data/{lib → ruby/server/lib}/roma/tools/tribunus.rb +0 -0
  84. data/ruby/server/lib/roma/version.rb +4 -0
  85. data/{lib → ruby/server/lib}/roma/write_behind.rb +1 -0
  86. data/ruby/server/test/config4mhash.rb +68 -0
  87. data/ruby/server/test/config4storage_error.rb +69 -0
  88. data/{lib/roma/config.rb → ruby/server/test/config4test.rb} +6 -3
  89. data/{test → ruby/server/test}/rcirb.rb +0 -1
  90. data/{test → ruby/server/test}/roma-test-utils.rb +21 -8
  91. data/{test → ruby/server/test}/run-test.rb +3 -2
  92. data/ruby/server/test/storage_error_storage.rb +37 -0
  93. data/ruby/server/test/t_command_definition.rb +326 -0
  94. data/{test → ruby/server/test}/t_cpdata.rb +9 -3
  95. data/{test → ruby/server/test}/t_listplugin.rb +48 -12
  96. data/ruby/server/test/t_mapcountplugin.rb +231 -0
  97. data/ruby/server/test/t_mapplugin.rb +131 -0
  98. data/ruby/server/test/t_mhash.rb +222 -0
  99. data/ruby/server/test/t_rclient.rb +199 -0
  100. data/{test → ruby/server/test}/t_routing_data.rb +56 -0
  101. data/{test → ruby/server/test}/t_storage.rb +107 -111
  102. data/ruby/server/test/t_storage_error.rb +61 -0
  103. data/ruby/server/test/t_writebehind.rb +374 -0
  104. metadata +150 -82
  105. data/bin/recoverlost_alist +0 -8
  106. data/bin/romad +0 -7
  107. data/lib/roma/command/mh_command_receiver.rb +0 -117
  108. data/lib/roma/command/receiver.rb +0 -287
  109. data/lib/roma/event/handler.rb +0 -159
  110. data/lib/roma/plugin/plugin_debug.rb +0 -19
  111. data/lib/roma/tools/recoverlost_lib.rb +0 -217
  112. data/lib/roma/version.rb +0 -4
  113. data/test/t_rclient.rb +0 -318
  114. data/test/t_writebehind.rb +0 -200
@@ -18,29 +18,7 @@ module Roma
18
18
  @ext_name = 'dbm'
19
19
  end
20
20
 
21
- def clean_up(t,unit_test_flg=nil)
22
- n = 0
23
- nt = Time.now.to_i
24
- @hdb.each_index{ |i|
25
- delkey = []
26
- @hdb[i].each{ |k, v|
27
- vn, last, clk, expt = unpack_header(v)
28
- if nt > expt && t > last
29
- n += 1
30
- delkey << k
31
- end
32
- if unit_test_flg
33
- closedb
34
- end
35
- }
36
- delkey.each{ |k| @hdb[i].out(k) }
37
- }
38
- n
39
- rescue => e
40
- raise NoMethodError(e.message)
41
- end
42
-
43
- def each_clean_up(t, vnhash)
21
+ def each_clean_up(t, vnhash)
44
22
  @do_clean_up = true
45
23
  nt = Time.now.to_i
46
24
  @hdb.each{ |hdb|
File without changes
@@ -6,6 +6,33 @@ module Roma
6
6
 
7
7
  class TCStorage < BasicStorage
8
8
  include TokyoCabinet
9
+
10
+ class TokyoCabinet::HDB
11
+ alias get_org get
12
+ def get key
13
+ ret = get_org key
14
+ if ret == nil && ecode != ENOREC
15
+ raise StorageException, errmsg(ecode)
16
+ end
17
+ ret
18
+ end
19
+
20
+ alias put_org put
21
+ def put key, value
22
+ ret = put_org key, value
23
+ raise StorageException, errmsg(ecode) unless ret
24
+ ret
25
+ end
26
+
27
+ alias out_org out
28
+ def out key
29
+ ret = out_org key
30
+ if ret == false && ecode != ENOREC
31
+ raise StorageException, errmsg(ecode)
32
+ end
33
+ ret
34
+ end
35
+ end
9
36
 
10
37
  def initialize
11
38
  super
@@ -22,6 +49,39 @@ module Roma
22
49
  ret
23
50
  end
24
51
 
52
+ def opendb
53
+ create_div_hash
54
+ path = ''
55
+ @storage_path.split('/').each{|p|
56
+ if p.length==0
57
+ path = '/'
58
+ next
59
+ end
60
+ path << p
61
+ Dir::mkdir(path) unless File.exist?(path)
62
+ path << '/'
63
+ }
64
+
65
+ @fname_lock = "#{@storage_path}/lock"
66
+ if File.exist?(@fname_lock)
67
+ raise RuntimeError.new("Lock file already exists.")
68
+ end
69
+ open(@fname_lock,"w"){}
70
+
71
+ @divnum.times{ |i|
72
+ @hdb[i] = open_db("#{@storage_path}/#{i}.#{@ext_name}")
73
+ }
74
+ end
75
+
76
+ def closedb
77
+ stop_clean_up
78
+ buf = @hdb; @hdb = []
79
+ buf.each{ |hdb| close_db(hdb) }
80
+
81
+ File.unlink(@fname_lock) if @fname_lock
82
+ @fname_lock = nil
83
+ end
84
+
25
85
  protected
26
86
 
27
87
  def set_options(hdb)
@@ -68,7 +128,7 @@ module Roma
68
128
  hdb = HDB::new
69
129
 
70
130
  set_options(hdb)
71
-
131
+
72
132
  if !hdb.open(fname, HDB::OWRITER | HDB::OCREAT | HDB::ONOLCK)
73
133
  ecode = hdb.ecode
74
134
  raise RuntimeError.new("tcdb open error #{hdb.errmsg(ecode)}")
@@ -80,7 +140,7 @@ module Roma
80
140
  if !hdb.close
81
141
  ecode = hdb.ecode
82
142
  raise RuntimeError.new("tcdb close error #{hdb.errmsg(ecode)}")
83
- end
143
+ end
84
144
  end
85
145
 
86
146
  end # class TCStorage
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # usage:chg_redundancy n address port > routingfile
4
+ #
5
+ require 'roma/logging/rlogger'
6
+ require 'roma/messaging/con_pool'
7
+ require 'roma/routing/routing_data'
8
+ require 'roma/client/sender'
9
+
10
+ def get_routing_data(nid)
11
+ sender = Roma::Client::Sender.new
12
+ sender.send_routedump_command(nid)
13
+ end
14
+
15
+ if ARGV.length != 3
16
+ STDERR.puts "usage:#{File.basename($0)} n address port";exit
17
+ end
18
+
19
+ rn = ARGV[0].to_i
20
+ STDERR.puts "must be n >= 1.";exit if rn < 1
21
+
22
+ rd = get_routing_data("#{ARGV[1]}_#{ARGV[2]}")
23
+ STDERR.puts "can not get the routing data.";exit unless rd
24
+
25
+ # clear logic clock
26
+ rd.v_clk.keys.each{|k| rd.v_clk[k] = 0 }
27
+
28
+ if rd.rn > rn
29
+ rd.v_idx.keys.each{|k|
30
+ rd.v_idx[k] = rd.v_idx[k][0..(rn - 1)]
31
+ }
32
+ end
33
+
34
+ rd.rn = rn
35
+ rd.nodes.sort!
36
+ STDOUT.puts YAML.dump(rd)
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ require 'optparse'
4
+
5
+ module Roma
6
+ module Storage
7
+ end
8
+ Storage::autoload(:TCStorage,'roma/storage/tc_storage')
9
+ Storage::autoload(:DbmStorage,'roma/storage/dbm_storage')
10
+ Storage::autoload(:SQLite3Storage,'roma/storage/sqlite3_storage')
11
+
12
+ class KeyAccess
13
+
14
+ def initialize(argv)
15
+ options(argv)
16
+
17
+ each_hash(@path){|hname, dir|
18
+ puts "hash : #{hname}"
19
+ st = open_storage(dir)
20
+
21
+ vn, last, clk, expt, value = st.get_raw2(@key)
22
+ if vn
23
+ if @sv
24
+ puts "vnode: #{vn}"
25
+ puts "last : #{Time.at(last)}"
26
+ puts "clock: #{clk}"
27
+ puts "expt : #{Time.at(expt)}"
28
+ begin
29
+ puts "value #{Marshal.load(value)}"
30
+ rescue
31
+ puts "value: #{value}"
32
+ end
33
+ else
34
+ puts "exist"
35
+ end
36
+ st.closedb
37
+ return
38
+ end
39
+
40
+ st.closedb
41
+ }
42
+ puts "not exist"
43
+ end
44
+
45
+ def options(argv)
46
+ opts = OptionParser.new
47
+ opts.banner="usage:#{File.basename($0)} storage-path key"
48
+
49
+ @sv = false
50
+ opts.on("-v","--value","show value") { |v| @sv = true }
51
+
52
+ opts.parse!(argv)
53
+ raise OptionParser::ParseError.new if argv.length < 2
54
+ @path = argv[0]
55
+ @key = argv[1]
56
+ rescue OptionParser::ParseError => e
57
+ STDERR.puts opts.help
58
+ exit 1
59
+ end
60
+
61
+ def each_hash(path)
62
+ Dir::glob("#{path}/*").each{|dir|
63
+ next unless File::directory?(dir)
64
+ hname = dir[dir.rindex('/')+1..-1]
65
+ yield hname,dir
66
+ }
67
+ end
68
+
69
+ def open_storage(path)
70
+ unless File::directory?(path)
71
+ STDERR.puts "#{path} dose not found."
72
+ return nil
73
+ end
74
+
75
+ # get a file extension
76
+ ext = File::extname(Dir::glob("#{path}/0.*")[0])[1..-1]
77
+ # count a number of divided files
78
+ divnum = Dir::glob("#{path}/*.#{ext}").length
79
+
80
+ st = new_storage(ext)
81
+ st.divnum = divnum
82
+ st.vn_list = []
83
+ st.storage_path = path
84
+ st.opendb
85
+ st
86
+ end
87
+
88
+ def new_storage(ext)
89
+ case(ext)
90
+ when 'tc'
91
+ return ::Roma::Storage::TCStorage.new
92
+ when 'dbm'
93
+ return Roma::Storage::DbmStorage.new
94
+ when 'sql3'
95
+ return Roma::Storage::SQLite3Storage.new
96
+ else
97
+ return nil
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+
105
+ Roma::KeyAccess.new(ARGV)
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # usage:key_list storage-path [param_sleep(sec)]
4
+ #
5
+ module Roma
6
+ module Storage
7
+ end
8
+ Storage::autoload(:TCStorage,'roma/storage/tc_storage')
9
+ Storage::autoload(:DbmStorage,'roma/storage/dbm_storage')
10
+ Storage::autoload(:SQLite3Storage,'roma/storage/sqlite3_storage')
11
+
12
+ class KeyList
13
+
14
+ def initialize(strgpath, param_sleep)
15
+ each_hash(strgpath){|hname, dir|
16
+ STDERR.puts "### #{hname} #{dir}"
17
+ st = open_storage(dir)
18
+
19
+ c = 0
20
+ n = st.true_length
21
+ m = n / 100
22
+ m = 1 if m < 1
23
+ st.divnum.times{|i|
24
+ st.each_hdb_dump(i){|data|
25
+ c += 1
26
+ STDERR.print "#{c}/#{n}\r" if c % m == 0
27
+ vn, last, clk, expt, klen = data.unpack('NNNNN')
28
+ key, = data[20..-1].unpack("a#{klen}")
29
+ STDOUT.puts key
30
+ sleep param_sleep
31
+ }
32
+ }
33
+
34
+ st.closedb
35
+ STDERR.puts "\ndone"
36
+ }
37
+ end
38
+
39
+ def each_hash(path)
40
+ Dir::glob("#{path}/*").each{|dir|
41
+ next unless File::directory?(dir)
42
+ hname = dir[dir.rindex('/')+1..-1]
43
+ yield hname,dir
44
+ }
45
+ end
46
+
47
+ def open_storage(path)
48
+ unless File::directory?(path)
49
+ STDERR.puts "#{path} dose not found."
50
+ return nil
51
+ end
52
+
53
+ # get a file extension
54
+ ext = File::extname(Dir::glob("#{path}/0.*")[0])[1..-1]
55
+ # count a number of divided files
56
+ divnum = Dir::glob("#{path}/*.#{ext}").length
57
+
58
+ st = new_storage(ext)
59
+ st.divnum = divnum
60
+ st.vn_list = []
61
+ st.storage_path = path
62
+ st.opendb
63
+ st
64
+ end
65
+
66
+ def new_storage(ext)
67
+ case(ext)
68
+ when 'tc'
69
+ return ::Roma::Storage::TCStorage.new
70
+ when 'dbm'
71
+ return Roma::Storage::DbmStorage.new
72
+ when 'sql3'
73
+ return Roma::Storage::SQLite3Storage.new
74
+ else
75
+ return nil
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+
83
+ if ARGV.length < 1
84
+ STDERR.puts "usage:key_list storage-path [param_sleep(sec)]"
85
+ exit
86
+ end
87
+
88
+ if ARGV[1]
89
+ param_sleep = ARGV[1].to_f
90
+ else
91
+ param_sleep = 0.001
92
+ end
93
+
94
+ Roma::KeyList.new(ARGV[0], param_sleep)
@@ -0,0 +1,535 @@
1
+ require 'pathname'
2
+ require 'yaml'
3
+ require 'fileutils'
4
+
5
+ module Roma
6
+
7
+ class Mkconfig
8
+ TREE_TOP = "menu"
9
+ LIB_PATH = Pathname(__FILE__).dirname.parent.parent
10
+ CONFIG_PATH = File.join("roma", "config.rb")
11
+ CONFIG_FULL_PATH = File.expand_path(File.join(LIB_PATH, CONFIG_PATH))
12
+ CONFIG_OUT_PATH = File.expand_path(File.join(Pathname.pwd, "config.rb"))
13
+ PLUGIN_DIR = File.expand_path(File.join(LIB_PATH, File.join("roma", "plugin")))
14
+ BNUM_COEFFICIENT = 2 #reccomend1-4.
15
+ TC_FILE = 10
16
+ REDUNDANCY = 2
17
+ DEFAULT_ROMA_CONNECTION = 12
18
+ RUBY_CONNECTION = 10
19
+ JAVA_CONNECTION = 30
20
+ PHP_CONNECTION = 256
21
+ KB = 1024
22
+ GB = 1024 * 1024 * 1024
23
+ OS_MEMORY_SIZE = 2 * GB
24
+ END_MSG = ["exit", "quit", "balse"]
25
+
26
+ class Base
27
+ attr_accessor :all, :flag
28
+
29
+ def initialize
30
+ flag = false
31
+ @all = YAML.load <<-YAML
32
+ menu:
33
+ name:
34
+ path_name: menu
35
+ message: Please select by number.
36
+ choice:
37
+ - Select storage
38
+ - Select plugin
39
+ - Calculate File Descriptor
40
+ - Save
41
+ next:
42
+ - storage
43
+ - plugin
44
+ - fd_server
45
+ - save
46
+ storage:
47
+ name: selected_storage
48
+ path_name: storage
49
+ message: Please select by number.
50
+ choice:
51
+ - Ruby Hash
52
+ - Tokyo Cabinet
53
+ next:
54
+ - menu
55
+ - memory
56
+ memory:
57
+ name: memory_size_GB
58
+ path_name:
59
+ message: How big memory size? Please measure in GB.
60
+ next: process
61
+ process:
62
+ name: process_num
63
+ path_name:
64
+ message: How many run ROMA process per machine?
65
+ next: server
66
+ server:
67
+ name: server_num
68
+ path_name:
69
+ message: How many machine run as ROMA server?
70
+ next: data
71
+ data:
72
+ name: data_num
73
+ path_name:
74
+ message: How many data will you store?
75
+ next: key
76
+ key:
77
+ name: key_size_KB
78
+ path_name:
79
+ message: How big is key size per data? Please measure in KB.
80
+ next: value
81
+ value:
82
+ name: value_size_KB
83
+ path_name:
84
+ message: How big is value size per data? Please measure in KB.
85
+ next: menu
86
+ plugin:
87
+ name: selected_plugin
88
+ path_name: plugin
89
+ message: Please select by number.
90
+ choice:
91
+ #{load_path(PLUGIN_DIR) << "Select all plugins"}
92
+ next:
93
+ #{
94
+ r = Array.new
95
+ load_path(PLUGIN_DIR).count.times{ r << "continue" }
96
+ r << "menu"
97
+ r
98
+ }
99
+ store_type: Array
100
+ continue:
101
+ name:
102
+ path_name:
103
+ message: Please select by number.
104
+ choice:
105
+ - Select more
106
+ - No more
107
+ next:
108
+ - plugin
109
+ - menu
110
+ fd_server:
111
+ name: server_num
112
+ path_name: FileDescriptor
113
+ message: How many machine run as ROMA server?
114
+ next: fd_client
115
+ fd_client:
116
+ name: client_num
117
+ path_name:
118
+ message: How many machine run as ROMA client?
119
+ next: language
120
+ language:
121
+ name: client_language
122
+ path_name:
123
+ message: Please select programming language of client by number.
124
+ choice:
125
+ - Ruby
126
+ - Java
127
+ - PHP
128
+ next:
129
+ - menu
130
+ - menu
131
+ - menu
132
+ save: END
133
+ YAML
134
+ end
135
+
136
+ def keys
137
+ all.keys
138
+ end
139
+
140
+ def [](s)
141
+ all[s]
142
+ end
143
+
144
+ def load_path(path)
145
+ ret = Array.new
146
+ files = Dir::entries(path)
147
+ files.each do |file|
148
+ ret << file if File::ftype(File.join(path, file)) == "file"
149
+ end
150
+ ret
151
+ end
152
+
153
+ def print_question(key)
154
+ target = all[key]
155
+
156
+ print "#{target["message"]}\n"
157
+
158
+ if target.key?("choice")
159
+ target["choice"].each_with_index do |k, i|
160
+ print "[#{i + 1}] #{k}\n"
161
+ end
162
+ end
163
+ end
164
+
165
+ def next (key, input)
166
+ target = all[key]["next"]
167
+
168
+ if target.class == Array
169
+ return target[input.to_i - 1]
170
+ else
171
+ return target
172
+ end
173
+ end
174
+ end
175
+
176
+ class Input
177
+ module InputReadline
178
+ def get_line
179
+ return Readline.readline("> ", false)
180
+ end
181
+ end
182
+
183
+ module InputSimple
184
+ def get_line
185
+ print ">"
186
+ return gets.chomp!
187
+ end
188
+ end
189
+
190
+ def initialize
191
+ begin
192
+ require "readline"
193
+ rescue LoadError
194
+ self.extend InputSimple
195
+ return
196
+ end
197
+ self.extend InputReadline
198
+ end
199
+ end
200
+
201
+ class Config_status
202
+ attr_accessor :name, :value, :print, :default_value
203
+ def initialize(hash, input, store_type = nil)
204
+ @name = hash["name"]
205
+ @value = input
206
+ if store_type == "Array"
207
+ @value = Array.new
208
+ @value << input
209
+ end
210
+ @print = true
211
+ end
212
+ end
213
+
214
+ class Box
215
+ def self.print_edge(width)
216
+ print "+"
217
+ width.times { print "-" }
218
+ print "+\n"
219
+ end
220
+
221
+ def self.print_with_box(arg)
222
+ return if arg.count == 0
223
+
224
+ if arg.class == Hash
225
+ strs = Array.new
226
+ arg.each do |k, v|
227
+ strs << "#{k}: #{arg[k]}"
228
+ end
229
+ arg = strs
230
+ end
231
+
232
+ width = max_length(arg) + 1
233
+ print_edge(width)
234
+
235
+ arg.each do |s|
236
+ print "|#{s}"
237
+ (width - s.length).times do
238
+ print " "
239
+ end
240
+ print "|\n"
241
+ end
242
+
243
+ print_edge(width)
244
+ end
245
+
246
+ private
247
+
248
+ def self.max_length(arg)
249
+ max = 0
250
+ arg.each do |s|
251
+ max = s.length if s.length > max
252
+ end
253
+ max
254
+ end
255
+ end
256
+
257
+ class Calculate
258
+ def self.get_bnum(res)
259
+ ans = res["data"].value.to_i * BNUM_COEFFICIENT * REDUNDANCY / res["server"].value.to_i / TC_FILE
260
+ return ans
261
+ end
262
+
263
+ def self.get_xmsize_max(res)
264
+ ans = (res["memory"].value.to_i * GB - OS_MEMORY_SIZE) / res["process"].value.to_i / TC_FILE
265
+ if ans <= 0
266
+ ans = res["memory"].value.to_i * GB / 2 / res["process"].value.to_i / TC_FILE
267
+ end
268
+ return ans
269
+ end
270
+
271
+ def self.get_xmsize_min(res)
272
+ ans = (res["key"].value.to_i * KB + res["value"].value.to_i * KB) * res["data"].value.to_i * REDUNDANCY / res["server"].value.to_i / res["process"].value.to_i / TC_FILE
273
+ ans = ans
274
+ end
275
+
276
+ def self.get_fd(res)
277
+ res["fd_server"].value.to_i * connection_num(res) + (res["fd_client"].value.to_i- 1) * DEFAULT_ROMA_CONNECTION * 2
278
+ end
279
+
280
+ def self.connection_num(res)
281
+ case res["language"].value
282
+ when "Ruby"
283
+ connection = RUBY_CONNECTION
284
+ when "Java"
285
+ connection = JAVA_CONNECTION
286
+ when "PHP"
287
+ connection = PHP_CONNECTION
288
+ end
289
+
290
+ return connection
291
+ end
292
+ end
293
+
294
+ def initialize(mode = :no_menu)
295
+ @base = Base.new
296
+ @results = Hash::new
297
+ @next_hash = TREE_TOP
298
+ begin
299
+ @defaults = load_config([:STORAGE_CLASS, :STORAGE_OPTION, :PLUGIN_FILES])
300
+ rescue LoadError
301
+ puts 'Not found config.rb file.'
302
+ return
303
+ rescue
304
+ p $!
305
+ puts "Content of config.rb is wrong."
306
+ return
307
+ end
308
+ mkconfig(mode)
309
+ end
310
+
311
+ def load_config(targets)
312
+ require CONFIG_PATH
313
+ d_value = Hash.new
314
+ Config.constants.each do |cnst|
315
+ if targets.include?(cnst)
316
+ d_value[cnst] = Config.const_get(cnst)
317
+ end
318
+ end
319
+ return d_value
320
+ end
321
+
322
+ def mkconfig(mode)
323
+ skip = skip_menu!(mode)
324
+ while true
325
+ clear_screen
326
+ skip.call if @next_hash == "menu"
327
+ break if end?(@base[@next_hash])
328
+ Box.print_with_box(@defaults)
329
+ print_status(@results)
330
+ @base.print_question(@next_hash)
331
+ input = get_input(@base[@next_hash])
332
+ if END_MSG.include?(input)
333
+ break if exit?
334
+ else
335
+ @results = store_result(@results, @base, @next_hash, input)
336
+ @next_hash = @base.next(@next_hash, input)
337
+ end
338
+ end
339
+ end
340
+
341
+ def clear_screen
342
+ print "\e[H\e[2J"
343
+ end
344
+
345
+ def skip_menu!(menu)
346
+ return Proc.new {} if menu == :with_menu
347
+
348
+ i = 0
349
+ return Proc.new do
350
+ @next_hash = @base["menu"]["next"][i]
351
+ i += 1
352
+ end
353
+ end
354
+
355
+ def end?(s)
356
+ if s == "END"
357
+ save_data(@results)
358
+ true
359
+ end
360
+ end
361
+
362
+ def print_status(results)
363
+ strs = Array.new
364
+ results.each_value do |v|
365
+ strs << "#{v.name} : #{v.value}"
366
+ end
367
+ Box.print_with_box(strs)
368
+ end
369
+
370
+ def get_input(hash)
371
+ receiver = Input.new
372
+ input = ""
373
+
374
+ while !correct_in?(hash,input)
375
+ input = receiver.get_line
376
+ end
377
+
378
+ input
379
+ end
380
+
381
+ def correct_in?(hash,input)
382
+ if END_MSG.include?(input)
383
+ return true
384
+ end
385
+
386
+ if hash == "continue"
387
+ if (input == "y" || input == "n")
388
+ return true
389
+ end
390
+ else
391
+ if hash.key?('choice')
392
+ if hash['choice'].count >= input.to_i && input.to_i > 0
393
+ return true
394
+ end
395
+ else
396
+ if 0 < input.to_i
397
+ return true
398
+ end
399
+ end
400
+ end
401
+
402
+ return false
403
+ end
404
+
405
+ def exit?
406
+ question = "Settings are not saved. Really exit? [y/n]\n"
407
+ receiver = Input.new
408
+ input = ""
409
+
410
+ print question
411
+ input = receiver.get_line
412
+ if input == "y"
413
+ print "bye.\n"
414
+ true
415
+ else
416
+ print "Continue.\n"
417
+ sleep 1
418
+ false
419
+ end
420
+ end
421
+
422
+ def store_result(results, base, hash, input)
423
+ target = base[hash]
424
+
425
+ return results if !target["name"]
426
+
427
+ if target.key?("choice")
428
+ if target["store_type"] == "Array"
429
+ if base.flag
430
+ results[hash].value << target["choice"][input.to_i - 1] if !results[hash].value.include?(target["choice"][input.to_i - 1])
431
+ else
432
+ results[hash] = Config_status.new(target, target["choice"][input.to_i - 1], target["store_type"])
433
+ base.flag = true
434
+ end
435
+
436
+ if input.to_i == target["choice"].count
437
+ results[hash].value = target["choice"][0..-2]
438
+ end
439
+ else
440
+ results[hash] = Config_status.new(target, target["choice"][input.to_i - 1])
441
+ end
442
+ else
443
+ results[hash] = Config_status.new(target, input)
444
+ end
445
+
446
+ base.flag = false if hash == "menu"
447
+ return results
448
+ end
449
+
450
+ def save_data(res)
451
+ if res.key?("storage")
452
+ if res["storage"].value == "Ruby Hash"
453
+ req = "rh_storage"
454
+ storage = "RubyHashStorage"
455
+ end
456
+
457
+ if res["storage"].value == "Tokyo Cabinet"
458
+ req = "tc_storage"
459
+ storage = "TCStorage"
460
+ bnum = Calculate.get_bnum(res)
461
+ bnum = 5000000 if bnum < 5000000
462
+ xmsiz = Calculate.get_xmsize_max(res)
463
+ end
464
+ end
465
+
466
+ if res.key?("fd_server")
467
+ fd = Calculate.get_fd(res)
468
+ print "\r\nPlease set FD bigger than #{fd}.\r\n\r\n"
469
+ end
470
+
471
+ body = ""
472
+ open(CONFIG_FULL_PATH, "r") do |f|
473
+ body = f.read
474
+ end
475
+
476
+ if req
477
+ body = ch_assign(body, "require", " ", "roma\/storage\/#{req}")
478
+ body = ch_assign(body, "STORAGE_CLASS", "Roma::Storage::#{storage}")
479
+
480
+ if req == "rh_storage"
481
+ body = ch_assign(body, "STORAGE_OPTION","")
482
+ end
483
+
484
+ if req == "tc_storage"
485
+ body = ch_assign(body, "STORAGE_OPTION", "bnum=#{bnum}\#xmsiz=#{xmsiz}\#opts=d#dfunit=10")
486
+ end
487
+ end
488
+
489
+ if res.key?("plugin")
490
+ body = ch_assign(body, "PLUGIN_FILES", res["plugin"].value)
491
+ end
492
+
493
+ open(CONFIG_OUT_PATH, "w") do |f|
494
+ f.flock(File::LOCK_EX)
495
+ f.puts body
496
+ f.truncate(f.tell)
497
+ f.flock(File::LOCK_UN)
498
+ end
499
+
500
+ puts "Before"
501
+ Box.print_with_box(@defaults)
502
+
503
+ re_require(CONFIG_PATH, CONFIG_FULL_PATH, Config)
504
+ results = load_config([:STORAGE_CLASS, :STORAGE_OPTION, :PLUGIN_FILES])
505
+ print "\r\nAfter\r\n"
506
+ Box.print_with_box(results)
507
+ print "\r\nMkconfig is finish.\r\n\r\n"
508
+ end
509
+
510
+ def ch_assign(text, exp, sep = " = ", str)
511
+ sep = " = " if sep == "="
512
+ text = text.gsub(/(\s*#{exp}).*/) do |s|
513
+ name = $1
514
+ if str.class == String
515
+ if str =~ /::/ || str =~ /^\d+$/
516
+ name + sep + str
517
+ else
518
+ name + sep + str.inspect
519
+ end
520
+ else
521
+ name + sep + str.to_s.sub("\\", "")
522
+ end
523
+ end
524
+ end
525
+
526
+ def re_require(lib_path, path, c_obj)
527
+ $".delete(File.expand_path(path))
528
+ c_obj.constants.each do |cnst|
529
+ c_obj.class_eval { remove_const cnst }
530
+ end
531
+ require lib_path
532
+ end
533
+
534
+ end # Mkconfig
535
+ end # module Roma