-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinary_mask.rb
More file actions
84 lines (61 loc) · 1.41 KB
/
binary_mask.rb
File metadata and controls
84 lines (61 loc) · 1.41 KB
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
# frozen_string_literal: true
require 'date'
# Class that holds a date, bit-packed into an integer
class PackedDate
## BINARY MASKS AND CONSTANTS
YEAR_BITS = 9
MONTH_BITS = 5
YEAR_MASK = 0b11111111111111000000000
MONTH_MASK = 0b00000000000000111100000
DAY_MASK = 0b00000000000000000011111
ZERO_YEAR_MASK = 0b00000000000000111111111
ZERO_MONTH_MASK = 0b11111111111111000011111
ZERO_DAY_MASK = 0b11111111111111111100000
def initialize(date)
pack_date(date)
end
def packed
@packed
end
## PACK BITS
def self.from_date(date)
packed = date.year << YEAR_BITS
packed |= date.month << MONTH_BITS
packed |= date.day
new(packed)
end
def initialize(packed_date)
@packed = packed_date
end
## UNPACK BITS
def year
(@packed & YEAR_MASK) >> YEAR_BITS
end
def month
(@packed & MONTH_MASK) >> MONTH_BITS
end
def day
(@packed & DAY_MASK)
end
def date
Date.new(year, month, day)
end
## CHANGE BITS
def year=(new_year)
@packed = (@packed & ZERO_YEAR_MASK) | (new_year << YEAR_BITS)
end
def month=(new_month)
@packed = (@packed & ZERO_MONTH_MASK) | (new_month << MONTH_BITS)
end
def day=(new_day)
@packed = (@packed & ZERO_DAY_MASK) | new_day
end
end
date = PackedDate.from_date(Date.today)
packed = date.packed
pd = PackedDate.new(packed)
pd.packed
pd.year
pd.month
pd.day
pd.date