roma 0.8.2 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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