-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TSID as database primary keys in multi tenant environment #32
Comments
Hi @JuanCarlosGonzalez ! I think you could build a package com.example;
import com.github.f4b6a3.tsid.Tsid;
import com.github.f4b6a3.tsid.TsidFactory;
public class TsidGenerator {
private static final int nodeBits = 10;
public static Tsid next(int node) {
// setup a factory to be used in this call
TsidFactory factory = TsidFactory.builder() //
.withNodeBits(nodeBits) // max: 20
.withNode(node) // max: 2^nodeBits
.build();
// use the factory once
return factory.create();
}
// TODO: remove me
public static void main(String[] args) {
System.out.println(TsidGenerator.next(1000));
}
} The next example is closer to your approach. It intercepts the TSID and overrides its node ID before returning the TSID to the caller. You could use package com.example;
import com.github.f4b6a3.tsid.Tsid;
import com.github.f4b6a3.tsid.TsidFactory;
public class TsidGenerator2 {
// NOTE: change me if you want (max:20)
private static final int nodeBits = 10;
// NOTE: don't need to change from here
private static final int randBits = 22;
private static final int counterBits = randBits - nodeBits;
private static final long nodeMask = (1L << nodeBits) - 1L;
private static final long tsidMask = ~(nodeMask << counterBits);
private static final TsidFactory factory = TsidFactory.builder().withNodeBits(nodeBits).withNode(0L).build();
public static Tsid next(int node) {
// generate a TSID using the custom factory
final long tsid = factory.create().toLong();
// override the node ID, preserving the time stamp and counter/sequence
return Tsid.from((tsid & tsidMask) | ((node & nodeMask) << counterBits));
}
// TODO: remove me
private static void inspect() {
Tsid[] list = new Tsid[10000];
for (int node = 0; node < list.length; node++) {
list[node] = TsidGenerator2.next(node % (1 << nodeBits));
}
for (int node = 0; node < list.length; node++) {
Tsid tsid = list[node];
System.out.println(String.format(
"TSID hex: %s, TSID binary: %s, TSID time: %s, TSID counter/sequence: %d , input node: %d; output node: %d, equals: %s",
/* TSID hex */ Long.toUnsignedString(tsid.toLong(), 16), //
/* TSID binary */ tsid.encode(2), //
/* TSID time */ tsid.getInstant(), //
/* TSID counter/sequence */ tsid.getRandom() & tsidMask, //
/* input node */ node % (1 << nodeBits), //
/* output node */ tsid.getRandom() >>> counterBits, //
/* equals */ node % (1 << nodeBits) == tsid.getRandom() >>> counterBits));
}
System.out.println();
System.out.println("SETTINGS");
System.out.println("--------");
System.out.println("nodeBits: " + nodeBits);
System.out.println("counterBits: " + counterBits);
System.out.println("nodeMask: " + Long.toUnsignedString(nodeMask, 16));
System.out.println("tsidMask: " + Long.toUnsignedString(tsidMask, 16));
}
// TODO: remove me
public static void main(String[] args) {
inspect();
}
} Feel free to clone the repo and implement your own solution if you don't like the examples. Best regards. |
Hi Fabio. Thanks for your inspiring suggestions. I like the second approach too. Best regards, |
Hi,
First of all, thanks for this library. I haven't used it yet, but it looks promising. I'm working on a project with Spring/Hibernate/MySql classical stack on a multitenant environment, where there is a database catalog per tenant. Additionally, some tenants data could be consolidated in a different catalog as they belong to the same organization. Anyway, my requirement is to generate primary keys in a way where future clashes can be avoided. This is where this library fits. My initial thought was to assign a different node id for each tenant, but the library is designed assuming that node id is immutable. So, my questions are:
Thanks for your time.
Best regards,
Juan Carlos
The text was updated successfully, but these errors were encountered: