Skip to content

Instantly share code, notes, and snippets.

@mgodave
Created October 16, 2013 20:08
Show Gist options
  • Save mgodave/7013937 to your computer and use it in GitHub Desktop.
Save mgodave/7013937 to your computer and use it in GitHub Desktop.
CRDT user API PoC
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
import com.basho.riak.client.query.crdt.ops.CounterOp;
import com.basho.riak.client.query.crdt.ops.CrdtOp;
public class CounterMutationBuilder extends CrdtMutationBuilder implements CrdtTopLevel
{
private long delta = 0;
CounterMutationBuilder()
{
}
CounterMutationBuilder(long delta)
{
this.delta = delta;
}
public static CounterMutationBuilder newCounter()
{
return new CounterMutationBuilder();
}
public static CounterMutationBuilder increment()
{
return new CounterMutationBuilder(1);
}
public static CounterMutationBuilder decrement()
{
return new CounterMutationBuilder(-1);
}
public CounterMutationBuilder increment(long delta)
{
this.delta += delta;
return this;
}
public long getDelta()
{
return delta;
}
@Override
CrdtOp getOp()
{
return new CounterOp(delta);
}
}
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
import com.basho.riak.client.query.crdt.ops.CrdtOp;
import com.basho.riak.client.util.ByteArrayWrapper;
import java.nio.ByteBuffer;
import static com.basho.riak.client.operations.crdt.CounterMutationBuilder.increment;
import static com.basho.riak.client.operations.crdt.FlagMutationBuilder.enabled;
import static com.basho.riak.client.operations.crdt.RegisterMutationBuilder.registerValue;
public abstract class CrdtMutationBuilder
{
abstract CrdtOp getOp();
public static MapMutationBuilder forMap()
{
return new MapMutationBuilder();
}
public static SetMutationBuiler forSet()
{
return new SetMutationBuiler();
}
public static CounterMutationBuilder forCounter()
{
return new CounterMutationBuilder();
}
public static void main(String... args)
{
/**
* Increment a single counter
*/
CrdtMutationBuilder.forCounter().increment(1);
/**
* Add a single value to a set
*/
CrdtMutationBuilder.forSet().add(ByteArrayWrapper.create("value"));
/**
* Update a deeply nested structure
*/
CrdtMutationBuilder.forMap()
.add(ByteArrayWrapper.create("key1"),
forCounter().increment(1))
.add(ByteArrayWrapper.create("key2"),
forSet().add(ByteArrayWrapper.create("value")))
.addRegister(ByteArrayWrapper.create("key3"))
.addFlag(ByteArrayWrapper.create("key4"))
.add(ByteArrayWrapper.create("key5"), forMap()
.addFlag(ByteArrayWrapper.create("key5-1"))
.addRegister(ByteArrayWrapper.create("key5-2"))
.update(ByteArrayWrapper.create("key5-3"),
forCounter().increment(1)))
.addRegister(ByteArrayWrapper.create("key6"));
/**
* A cleaner, more accessible example. Update a user's info in a table
*/
// ByteArrayWrappers make it look messy, so define them all here.
ByteArrayWrapper numLogins = ByteArrayWrapper.create("logins");
ByteArrayWrapper lastLoginTime = ByteArrayWrapper.create("last-login");
ByteBuffer nowBinary = ByteBuffer.allocate(8).putLong(System.currentTimeMillis());
ByteArrayWrapper now = ByteArrayWrapper.create(nowBinary.array());
ByteArrayWrapper users = ByteArrayWrapper.create("users");
ByteArrayWrapper username = ByteArrayWrapper.create("username");
ByteArrayWrapper loggedIn = ByteArrayWrapper.create("logged-in");
// Create a builder for the user and update the values
MapMutationBuilder userMapUpdate = forMap()
.update(numLogins, increment())
.update(lastLoginTime, registerValue(now))
.update(loggedIn, enabled());
// Now create an update for the user's entry
MapMutationBuilder userInfoUpdate = forMap().update(users, forMap().update(username, userMapUpdate));
// TBD, pass userInfoUpdate to the operation to be updated
}
}
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
public interface CrdtTopLevel
{
}
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
import com.basho.riak.client.query.crdt.ops.CrdtOp;
import com.basho.riak.client.query.crdt.ops.FlagOp;
public class FlagMutationBuilder extends CrdtMutationBuilder implements CrdtTopLevel
{
private boolean flag = false;
FlagMutationBuilder(boolean flag)
{
this.flag = flag;
}
FlagMutationBuilder()
{
}
public static FlagMutationBuilder newBuilder()
{
return new FlagMutationBuilder();
}
public static FlagMutationBuilder enabled()
{
return new FlagMutationBuilder(true);
}
public static FlagMutationBuilder disabled()
{
return new FlagMutationBuilder(false);
}
private FlagMutationBuilder setFlag(boolean flag)
{
this.flag = flag;
return this;
}
private boolean isSet()
{
return flag;
}
@Override
CrdtOp getOp()
{
return new FlagOp(flag);
}
}
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
import com.basho.riak.client.query.crdt.ops.CrdtOp;
import com.basho.riak.client.query.crdt.ops.MapOp;
import com.basho.riak.client.util.ByteArrayWrapper;
import java.util.HashSet;
import java.util.Set;
public class MapMutationBuilder extends CrdtMutationBuilder implements CrdtTopLevel
{
private final Set<MapOp.MapField> adds = new HashSet<MapOp.MapField>();
private final Set<MapOp.MapField> removes = new HashSet<MapOp.MapField>();
private final Set<MapOp.MapUpdate> updates = new HashSet<MapOp.MapUpdate>();
public MapMutationBuilder addCounter(ByteArrayWrapper key)
{
adds.add(new MapOp.MapField(MapOp.FieldType.COUNTER, key));
return this;
}
public MapMutationBuilder addRegister(ByteArrayWrapper key)
{
adds.add(new MapOp.MapField(MapOp.FieldType.REGISTER, key));
return this;
}
public MapMutationBuilder addFlag(ByteArrayWrapper key)
{
adds.add(new MapOp.MapField(MapOp.FieldType.FLAG, key));
return this;
}
public MapMutationBuilder addSet(ByteArrayWrapper key)
{
adds.add(new MapOp.MapField(MapOp.FieldType.SET, key));
return this;
}
public MapMutationBuilder addMap(ByteArrayWrapper key)
{
adds.add(new MapOp.MapField(MapOp.FieldType.MAP, key));
return this;
}
public MapMutationBuilder removeCounter(ByteArrayWrapper key)
{
removes.add(new MapOp.MapField(MapOp.FieldType.COUNTER, key));
return this;
}
public MapMutationBuilder removeRegister(ByteArrayWrapper key)
{
removes.add(new MapOp.MapField(MapOp.FieldType.REGISTER, key));
return this;
}
public MapMutationBuilder removeFlag(ByteArrayWrapper key)
{
removes.add(new MapOp.MapField(MapOp.FieldType.FLAG, key));
return this;
}
public MapMutationBuilder removeSet(ByteArrayWrapper key)
{
removes.add(new MapOp.MapField(MapOp.FieldType.SET, key));
return this;
}
public MapMutationBuilder removeMap(ByteArrayWrapper key)
{
removes.add(new MapOp.MapField(MapOp.FieldType.MAP, key));
return this;
}
public MapMutationBuilder add(ByteArrayWrapper key, MapMutationBuilder builder)
{
return update(key, builder);
}
public MapMutationBuilder add(ByteArrayWrapper key, SetMutationBuiler builder)
{
return update(key, builder);
}
public MapMutationBuilder add(ByteArrayWrapper key, CounterMutationBuilder builder)
{
return update(key, builder);
}
public MapMutationBuilder add(ByteArrayWrapper key, RegisterMutationBuilder builder)
{
return update(key, builder);
}
public MapMutationBuilder add(ByteArrayWrapper key, FlagMutationBuilder builder)
{
return update(key, builder);
}
public MapMutationBuilder update(ByteArrayWrapper key, MapMutationBuilder builder)
{
updates.add(new MapOp.MapUpdate(new MapOp.MapField(MapOp.FieldType.MAP, key), builder.getOp()));
return this;
}
public MapMutationBuilder update(ByteArrayWrapper key, SetMutationBuiler builder)
{
updates.add(new MapOp.MapUpdate(new MapOp.MapField(MapOp.FieldType.SET, key), builder.getOp()));
return this;
}
public MapMutationBuilder update(ByteArrayWrapper key, CounterMutationBuilder builder)
{
updates.add(new MapOp.MapUpdate(new MapOp.MapField(MapOp.FieldType.COUNTER, key), builder.getOp()));
return this;
}
public MapMutationBuilder update(ByteArrayWrapper key, RegisterMutationBuilder builder)
{
updates.add(new MapOp.MapUpdate(new MapOp.MapField(MapOp.FieldType.REGISTER, key), builder.getOp()));
return this;
}
public MapMutationBuilder update(ByteArrayWrapper key, FlagMutationBuilder builder)
{
updates.add(new MapOp.MapUpdate(new MapOp.MapField(MapOp.FieldType.FLAG, key), builder.getOp()));
return this;
}
@Override
CrdtOp getOp()
{
return new MapOp(adds, removes, updates);
}
}
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
import com.basho.riak.client.query.crdt.ops.CrdtOp;
import com.basho.riak.client.query.crdt.ops.RegisterOp;
import com.basho.riak.client.util.ByteArrayWrapper;
public class RegisterMutationBuilder extends CrdtMutationBuilder
{
private ByteArrayWrapper value = null;
RegisterMutationBuilder(ByteArrayWrapper value)
{
this.value = value;
}
RegisterMutationBuilder()
{
}
public static RegisterMutationBuilder registerValue(ByteArrayWrapper value)
{
return new RegisterMutationBuilder(value);
}
public static RegisterMutationBuilder emptyRegister()
{
return new RegisterMutationBuilder();
}
public RegisterMutationBuilder set(ByteArrayWrapper value)
{
this.value = value;
return this;
}
public RegisterMutationBuilder clear()
{
this.value = null;
return this;
}
public ByteArrayWrapper get()
{
return value;
}
@Override
CrdtOp getOp()
{
return new RegisterOp(value);
}
}
/*
* Copyright 2013 Basho Technologies Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.basho.riak.client.operations.crdt;
import com.basho.riak.client.query.crdt.ops.CrdtOp;
import com.basho.riak.client.query.crdt.ops.SetOp;
import com.basho.riak.client.util.ByteArrayWrapper;
import java.util.HashSet;
import java.util.Set;
public class SetMutationBuiler extends CrdtMutationBuilder
{
private final Set<ByteArrayWrapper> adds = new HashSet<ByteArrayWrapper>();
private final Set<ByteArrayWrapper> removes = new HashSet<ByteArrayWrapper>();
public SetMutationBuiler()
{
}
public SetMutationBuiler add(ByteArrayWrapper value)
{
this.adds.add(value);
return this;
}
public SetMutationBuiler remove(ByteArrayWrapper value)
{
this.removes.add(value);
return this;
}
public Set<ByteArrayWrapper> getAdds()
{
return adds;
}
public Set<ByteArrayWrapper> getRemoves()
{
return removes;
}
@Override
CrdtOp getOp()
{
return new SetOp(adds, removes);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment