def dump_lattice(self, value, typ=None, causal_dependencies={}): if not typ: if isinstance(value, set): return self.dump_lattice(value, SetLattice) elif isinstance(value, dict): return self.dump_lattice(value, MapLattice) elif isinstance(value, list): return self.dump_lattice(value, OrderedSetLattice) else: return self.dump_lattice(value, LWWPairLattice) if typ == SetLattice: result = set() for v in value: result.add(self.dump(v)) result = SetLattice(result) elif typ == MapLattice: result = {} for key in value: result[key] = self.dump_lattice(value[key]) result = MapLattice(result) elif typ == OrderedSetLattice: result = list() for v in value: result.append(self.dump(v)) result = OrderedSetLattice(ListBasedOrderedSet(result)) elif typ == LWWPairLattice: result = LWWPairLattice(generate_timestamp(0), self.dump(value)) elif typ == SingleKeyCausalLattice: # We assume that we will use the default vector clock for causal # metadata. data = SetLattice({self.dump(value)}) result = SingleKeyCausalLattice(DEFAULT_VC, data) elif typ == MultiKeyCausalLattice: # We assume that we will use the default vector clock for causal # metadata. data = SetLattice({self.dump(value)}) result = MultiKeyCausalLattice(DEFAULT_VC, MapLattice(causal_dependencies), data) else: raise ValueError(f'Unexpected lattice type: {str(typ)}') return result
def _deserialize(self, tup): if tup.lattice_type == LWW: # Deserialize last-writer-wins lattices val = LWWValue() val.ParseFromString(tup.payload) return LWWPairLattice(val.timestamp, val.value) elif tup.lattice_type == SET: # Deserialize unordered-set lattices s = SetValue() s.ParseFromString(tup.payload) result = set() for k in s.values: result.add(k) return SetLattice(result) elif tup.lattice_type == ORDERED_SET: # Deserialize ordered-set lattices res = ListBasedOrderedSet() val = SetValue() val.ParseFromString(tup.payload) for v in val.values: res.insert(v) return OrderedSetLattice(res) elif tup.lattice_type == SINGLE_CAUSAL: # Deserialize single-key causal lattices val = SingleKeyCausalValue() # Deserialize the vector_clock stored in the Protobuf into a # MapLattice, where each value is a MaxIntLattice of the VC # counter. vc = VectorClock(val.vector_clock, True) # Create a SetLattice with the value(s) stored by this lattice. values = set() for v in val.values(): values.add(v) return SingleKeyCasaulLattice(vc, SetLattice(values)) elif tup.lattice_type == MULTI_CAUSAL: # Deserialize multi-key causal lattices val = MultiKeyCausalValue() # Deserialize the vector_clock stored in the Protobuf into a # MapLattice, where each value is a MaxIntLattice of the VC # counter. vc = VectorClock(val.vector_clock, True) # Deserialize the set of dependencies of this key into a MapLattice # where the keys are names of other KVS keys and the values are # MapLattices that have the vector clocks for those keys. dep_map = {} for kv in val.dependencies: key = kv.key dep_map[key] = VectorClock(kv.vector_clock, True) # Create a SetLattice with the value(s) stored by this lattice. values = set() for v in val.values(): values.add(v) dependencies = MapLattice(dep_map) value = SetLattice(values) return MultiKeyCausalLattice(vc, dependencies, value) else: raise ValueError('Unsupported type cannot be serialized: ' + str(tup.lattice_type))