rbbt-util 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ require 'tokyocabinet'
2
+
3
+ class TCHash < TokyoCabinet::HDB
4
+ class OpenError < StandardError;end
5
+ class KeyFormatError < StandardError;end
6
+
7
+ Serializer = Marshal
8
+
9
+ FIELD_INFO_ENTRIES = {:fields => '__tokyocabinet_hash_fields', :key_field => '__tokyocabinet_hash_native_field'}
10
+ CONNECTIONS = {}
11
+
12
+ FIELD_INFO_ENTRIES.each do |entry, key|
13
+ class_eval do
14
+ define_method entry.to_s, proc{self[key]}
15
+ define_method entry.to_s + "=", proc{|value| write unless write?; self[key] = value}
16
+ end
17
+ end
18
+
19
+ alias original_get_brackets []
20
+ def [](key)
21
+ return nil unless String === key
22
+ result = self.original_get_brackets(key)
23
+ result ? Serializer.load(result) : nil
24
+ end
25
+
26
+ alias original_set_brackets []=
27
+ def []=(key,value)
28
+ raise KeyFormatError, "Key must be a String, its #{key.class.to_s}" unless String === key
29
+ write unless write?
30
+ self.original_set_brackets(key, Serializer.dump(value))
31
+ end
32
+
33
+ def values_at(*args)
34
+ args.collect do |key|
35
+ self[key]
36
+ end
37
+ end
38
+
39
+ alias original_keys keys
40
+ def keys
41
+ list = self.original_keys
42
+ indexes = FIELD_INFO_ENTRIES.values.collect do |field| list.index(field) end.compact
43
+ indexes.each do |index| list.delete_at index end
44
+ list
45
+ end
46
+
47
+ alias original_values values
48
+ def values
49
+ values = self.original_values
50
+ keys = self.original_keys
51
+ indexes = FIELD_INFO_ENTRIES.values.collect do |field| keys.index(field) end.compact
52
+ indexes.each do |index| values.delete_at index end
53
+
54
+ values.collect{|v| Serializer.load(v)}
55
+ end
56
+
57
+ def merge!(data)
58
+ new_data = {}
59
+ data.each do |key, values|
60
+ self[key] = values
61
+ end
62
+ end
63
+
64
+ # This version of each fixes a problem in ruby 1.9. It also
65
+ # removes the special entries
66
+ def each19(&block)
67
+ values = self.original_values.collect{|v| Serializer.load v}
68
+ keys = self.original_keys
69
+ indexes = FIELD_INFO_ENTRIES.values.collect do |field| keys.index(field) end.compact.sort.reverse
70
+ indexes.sort.reverse.each do |index| values.delete_at(index); keys.delete_at(index) end
71
+
72
+ keys.zip(values).each &block
73
+ end
74
+
75
+ alias original_each each
76
+ alias each each19
77
+
78
+ def collect
79
+ res = []
80
+ self.each{|k, v| res << [k,v]}
81
+ res
82
+ end
83
+
84
+ alias original_open open
85
+ def open(write = false)
86
+ flags = write ? TokyoCabinet::HDB::OWRITER | TokyoCabinet::HDB::OCREAT : TokyoCabinet::BDB::OREADER
87
+ if !self.original_open(@path_to_db, flags)
88
+ ecode = self.ecode
89
+ raise OpenError, "Open error: #{self.errmsg(ecode)}. Trying to open file #{@path_to_db}"
90
+ end
91
+ @write = write
92
+ end
93
+
94
+ def write?
95
+ @write
96
+ end
97
+
98
+ def write
99
+ self.close
100
+ self.open(true)
101
+ end
102
+
103
+ def read
104
+ self.close
105
+ self.open(false)
106
+ end
107
+
108
+ def initialize(path, write = false)
109
+ super()
110
+ @path_to_db = path
111
+
112
+ if write || ! File.exists?(@path_to_db)
113
+ self.open(true)
114
+ else
115
+ self.open(false)
116
+ end
117
+ end
118
+
119
+ def self.get(path, write = false)
120
+ d = CONNECTIONS[path] ||= self.new(path, false)
121
+ write ? d.write : d.read
122
+ d
123
+ end
124
+ end
@@ -0,0 +1,42 @@
1
+ require 'fileutils'
2
+
3
+ module TmpFile
4
+
5
+ TMPDIR = "/tmp/tmpfiles"
6
+ FileUtils.mkdir TMPDIR unless File.exist? TMPDIR
7
+
8
+ def self.tmpdir=(tmpdir)
9
+ TMPDIR.replace tmpdir
10
+ FileUtils.mkdir TMPDIR unless File.exist? TMPDIR
11
+ end
12
+
13
+ def self.tmpdir
14
+ TMPDIR
15
+ end
16
+
17
+
18
+ # Creates a random file name, with the given suffix and a random number
19
+ # up to +max+
20
+ def self.random_name(s = "", max = 10000000)
21
+ n = rand(max)
22
+ s << n.to_s
23
+ s
24
+ end
25
+
26
+ # Creates a random filename in the temporary directory
27
+ def self.tmp_file(s = "",max=10000000)
28
+ File.join(TMPDIR, random_name(s,max))
29
+ end
30
+
31
+ def self.with_file(content = nil, erase = true)
32
+ tmpfile = tmp_file
33
+
34
+ File.open(tmpfile, 'w') do |f| f.write content end if content != nil
35
+
36
+ result = yield(tmpfile)
37
+
38
+ FileUtils.rm tmpfile if File.exists?(tmpfile) and erase
39
+
40
+ result
41
+ end
42
+ end