… | |
… | |
72 | sub g_broadcast { |
72 | sub g_broadcast { |
73 | snd $_, @_ |
73 | snd $_, @_ |
74 | for other_globals; |
74 | for other_globals; |
75 | } |
75 | } |
76 | |
76 | |
77 | # add/replace a key in the database |
77 | # add/replace/del inside a family in the database |
78 | sub g_add($$$$) { |
78 | # @$dle must not contain any key in %$set |
79 | $LOCAL_DBS{$_[0]}{$_[1]}{$_[2]} = |
79 | sub g_upd { |
80 | $GLOBAL_DB {$_[1]}{$_[2]} = $_[3]; |
80 | my ($node, $family, $set, $del) = @_; |
81 | |
81 | |
82 | g_broadcast g_add => $_[1] => $_[2] => $_[3] |
82 | my $ldb = $LOCAL_DBS{$node}{$family} ||= {}; |
83 | if exists $GLOBAL_SLAVE{$_[0]}; |
83 | my $gdb = $GLOBAL_DB {$family} ||= {}; |
84 | |
84 | |
85 | # tell subscribers we have added or replaced a key |
85 | # add/replace keys |
86 | snd $_ => g_chg2 => $_[1], $_[2], $_[3] |
86 | while (my ($k, $v) = each %$set) { |
87 | for keys %{ $GLOBAL_MON{$_[1]} }; |
87 | $ldb->{$k} = |
88 | } |
88 | $gdb->{$k} = $v; |
|
|
89 | } |
89 | |
90 | |
90 | # delete a key from the database |
91 | my @del; # actual deletes |
91 | sub g_del($$$) { |
|
|
92 | delete $LOCAL_DBS{$_[0]}{$_[1]}{$_[2]}; |
|
|
93 | delete $LOCAL_DBS{$_[0]}{$_[1]} unless %{ $LOCAL_DBS{$_[0]}{$_[1]} }; |
|
|
94 | |
92 | |
95 | g_broadcast g_del => $_[1] => $_[2] |
93 | # take care of deletes |
96 | if exists $GLOBAL_SLAVE{$_[0]}; |
94 | keydel: |
|
|
95 | for my $k (@$del) { |
|
|
96 | delete $ldb->{$k}; |
|
|
97 | delete $gdb->{$k}; |
97 | |
98 | |
98 | delete $GLOBAL_DB{$_[1]}{$_[2]}; |
|
|
99 | delete $GLOBAL_DB{$_[1]} unless %{ $GLOBAL_DB{$_[1]} }; # could be moved below for |
|
|
100 | |
|
|
101 | # check if other node maybe still has the key, then we don't delete, but add |
99 | # check if some other node still has the key, then we don't delete, but change |
102 | for (values %LOCAL_DBS) { |
100 | for (values %LOCAL_DBS) { |
103 | if (exists $_->{$_[1]}{$_[2]}) { |
101 | if (exists $_->{$family}{$k}) { |
104 | my $val = $GLOBAL_DB{$_[1]}{$_[2]} = $_->{$_[1]}{$_[2]}; |
102 | $set->{$k} = $gdb->{$k} = $_->{$family}{$k}; |
105 | |
103 | |
106 | # tell subscribers we have added or replaced a key |
104 | next keydel; |
107 | snd $_ => g_chg2 => $_[1], $_[2], $val |
|
|
108 | for keys %{ $GLOBAL_MON{$_[1]} }; |
|
|
109 | |
|
|
110 | last; |
105 | } |
111 | } |
106 | } |
112 | } |
|
|
113 | |
107 | |
114 | # tell subscribers key is actually gone |
108 | push @del, $k; |
115 | snd $_ => g_chg2 => $_[1], $_[2] |
109 | } |
|
|
110 | |
|
|
111 | # family could be empty now |
|
|
112 | delete $GLOBAL_DB{$family} unless %$gdb; |
|
|
113 | delete $LOCAL_DBS{$node}{$family} unless %$ldb; |
|
|
114 | |
|
|
115 | g_broadcast g_upd => $family, $set, \@del |
|
|
116 | if exists $GLOBAL_SLAVE{$node}; |
|
|
117 | |
|
|
118 | # tell subscribers we have changed the family |
|
|
119 | snd $_ => g_chg2 => $family, $set, \@del |
116 | for keys %{ $GLOBAL_MON{$_[1]} }; |
120 | for keys %{ $GLOBAL_MON{$family} }; |
117 | } |
121 | } |
118 | |
122 | |
119 | # set the whole (node-local) database - previous value must be empty |
123 | # set the whole (node-local) database - previous value must be empty |
120 | sub g_set($$) { |
124 | sub g_set($$) { |
121 | my ($node, $db) = @_; |
125 | my ($node, $db) = @_; |
122 | |
126 | |
123 | while (my ($f, $k) = each %$db) { |
127 | while (my ($f, $k) = each %$db) { |
124 | g_add $node, $f => $_ => delete $k->{$_} |
128 | g_upd $node, $f, $k; |
125 | for keys %$k; |
|
|
126 | } |
129 | } |
127 | } |
130 | } |
128 | |
131 | |
129 | # delete all keys from a database |
132 | # delete all keys from a database |
130 | sub g_clr($) { |
133 | sub g_clr($) { |
131 | my ($node) = @_; |
134 | my ($node) = @_; |
132 | |
135 | |
133 | my $db = $LOCAL_DBS{$node}; |
136 | my $db = $LOCAL_DBS{$node}; |
|
|
137 | |
134 | while (my ($f, $k) = each %$db) { |
138 | while (my ($f, $k) = each %$db) { |
135 | g_del $node, $f => $_ |
139 | g_upd $node, $f, undef, [keys %$k]; |
136 | for keys %$k; |
|
|
137 | } |
140 | } |
138 | |
141 | |
139 | delete $LOCAL_DBS{$node}; |
142 | delete $LOCAL_DBS{$node}; |
140 | } |
143 | } |
141 | |
144 | |
… | |
… | |
148 | my $node = $SRCNODE->{id}; |
151 | my $node = $SRCNODE->{id}; |
149 | undef $GLOBAL_SLAVE{$node}; |
152 | undef $GLOBAL_SLAVE{$node}; |
150 | g_set $node, $db; |
153 | g_set $node, $db; |
151 | }; |
154 | }; |
152 | |
155 | |
153 | $NODE_REQ{g_add} = sub { |
|
|
154 | &g_add ($SRCNODE->{id}, @_); |
|
|
155 | }; |
|
|
156 | |
|
|
157 | $NODE_REQ{g_del} = sub { |
|
|
158 | &g_del ($SRCNODE->{id}, @_); |
|
|
159 | }; |
|
|
160 | |
|
|
161 | $NODE_REQ{g_set} = sub { |
156 | $NODE_REQ{g_set} = sub { |
162 | g_set $SRCNODE->{id}, $_[0]; |
157 | g_set $SRCNODE->{id}, @_; |
|
|
158 | }; |
|
|
159 | |
|
|
160 | $NODE_REQ{g_upd} = sub { |
|
|
161 | g_upd $SRCNODE->{id}, @_; |
163 | }; |
162 | }; |
164 | |
163 | |
165 | $NODE_REQ{g_find} = sub { |
164 | $NODE_REQ{g_find} = sub { |
166 | my ($node) = @_; |
165 | my ($node) = @_; |
167 | |
166 | |