public class PlanetID implements Serializable { private DatastoreService ds; public PlanetID() { ds = DatastoreServiceFactory.getDatastoreService(); } public long generateID() { return ds.allocateIds("Kind_That_Will_Never_Be_Used", 1L).getStart().getId(); } }
@Override public KeyRange allocateIds(Key parent, String kind, long num) { return this.ds.allocateIds(parent, kind, num); }
@Override public KeyRange allocateIds(String kind, long num) { return this.ds.allocateIds(kind, num); }
DatastoreService datastoreService = DatastoreServiceFactory.getDatastoreService(); KeyRange keyRange = datastoreService.allocateIds("CartItem", 1L); // you have ID here before save Entity item = new Entity(keyRange.getStart()); datastoreService.put(item);
public KeyRange allocateIds(Key parent, String kind, long num) { try { return inner.allocateIds(parent, kind, num); } catch (IllegalArgumentException e) { throw wrapIllegalArgumentException(e); } catch (DatastoreFailureException e) { throw wrapDatastoreFailureException(e); } }
public KeyRange allocateIds(String kind, long num) { try { return inner.allocateIds(kind, num); } catch (IllegalArgumentException e) { throw wrapIllegalArgumentException(e); } catch (DatastoreFailureException e) { throw wrapDatastoreFailureException(e); } }
/** * Preallocate a contiguous range of unique ids within the namespace of the * specified entity class. These ids can be used in concert with the normal * automatic allocation of ids when put()ing entities with null Long id fields. * * @param clazz must be a registered entity class with a Long or long id field. * @param num must be >= 1 and <= 1 billion */ public <T> KeyRange<T> allocateIds(Class<T> clazz, long num) { // Feels a little weird going directly to the DatastoreServiceFactory but the // allocateIds() method really is optionless. String kind = Key.getKind(clazz); return new KeyRange<T>(DatastoreServiceFactory.getDatastoreService().allocateIds(kind, num)); }
protected ValueGenerationBlock reserveBlock(long size) { if (sequenceName == null) { // shouldn't happen throw new IllegalStateException("sequence name is null"); } DatastoreServiceConfig config = ((DatastoreManager) storeMgr).getDefaultDatastoreServiceConfigForWrites(); DatastoreService ds = DatastoreServiceFactoryInternal.getDatastoreService(config); KeyRange range = ds.allocateIds(sequenceName, size); // Too bad we can't pass an iterable and construct the ids on demand. List<Long> ids = Utils.newArrayList(); long current = range.getStart().getId(); for (int i = 0; i < size; i++) { ids.add(current + i); } return new ValueGenerationBlock(ids); }
private long getInitialValue(String kind) { return service.allocateIds(kind, 1L).getStart().getId(); }
/** * Preallocate a contiguous range of unique ids within the namespace of the * specified entity class and the parent key. These ids can be used in concert with the normal * automatic allocation of ids when put()ing entities with null Long id fields. * * @param parentKeyOrEntity must be a legitimate parent for the class type. It need not * point to an existent entity, but it must be the correct type for clazz. * @param clazz must be a registered entity class with a Long or long id field, and * a parent key of the correct type. * @param num must be >= 1 and <= 1 billion */ public <T> KeyRange<T> allocateIds(Object parentKeyOrEntity, Class<T> clazz, long num) { Key<?> parent = this.getKey(parentKeyOrEntity); String kind = Key.getKind(clazz); // Feels a little weird going directly to the DatastoreServiceFactory but the // allocateIds() method really is optionless. return new KeyRange<T>(DatastoreServiceFactory.getDatastoreService().allocateIds(parent.getRaw(), kind, num)); }
@Test public void testAllocateId() throws Exception { KeyRange firstBlock = service.allocateIds(ALLOCATE_IDS_ENTITY, 10L); Assert.assertNotNull(firstBlock); Assert.assertEquals(10, firstBlock.getEnd().getId() - firstBlock.getStart().getId() + 1); Assert.assertEquals(10, firstBlock.getSize()); KeyRange secondBlock = service.allocateIds(ALLOCATE_IDS_ENTITY, 10L); Assert.assertNotNull(secondBlock); Assert.assertFalse("Allocated key ranges should not overlap.", rangeOverlap(firstBlock, secondBlock)); }
@Test public void testAllocateChild() { Entity parent = new Entity(ALLOCATE_IDS_ENTITY); parent.setProperty("name", "parent-" + System.currentTimeMillis()); Key parentKey = service.put(parent); final int allocateSize = 10; KeyRange range = service.allocateIds(parentKey, ALLOCATE_IDS_ENTITY, allocateSize); Entity child = new Entity(range.getStart()); Key key = service.put(child); // child with allocated key should have correct parent. Assert.assertEquals(parentKey, key.getParent()); }
@Test public void testOutOfRangeEntity() throws Exception { final long allocateNum = 5; // Range default namespace KeyRange range = service.allocateIds(ALLOCATE_IDS_ENTITY, allocateNum); Entity noParent = createTestEntity(ALLOCATE_IDS_ENTITY); assertEntityNotInRange(noParent, range); // Range with specified parent Entity parent = new Entity(ALLOCATE_IDS_ENTITY); Key parentKey = service.put(parent); KeyRange range2 = service.allocateIds(parentKey, ALLOCATE_IDS_ENTITY, allocateNum); Entity entity = createTestEntity(ALLOCATE_IDS_ENTITY, parentKey); assertEntityNotInRange(entity, range2); // In Range entity should have same parent Entity child = new Entity(range2.getStart()); Key childKey = service.put(child); // child with allocated key should have correct parent. Assert.assertEquals(parentKey, childKey.getParent()); }
@Test public void testCheckKeyRange() throws Exception { long initialValue = getInitialValue("OtherKind"); KeyRange kr1 = new KeyRange(null, "OtherKind", 1 + initialValue, 5 + initialValue); DatastoreService.KeyRangeState state1 = service.allocateIdRange(kr1); Assert.assertNotNull(state1); // imo, it could be either -- depending on the impl Assert.assertTrue(DatastoreService.KeyRangeState.CONTENTION == state1 || DatastoreService.KeyRangeState.EMPTY == state1); KeyRange kr2 = service.allocateIds("OtherKind", 6); Assert.assertNotNull(kr2); KeyRange kr3 = new KeyRange(null, "OtherKind", 2 + initialValue, 5 + initialValue); DatastoreService.KeyRangeState state2 = service.allocateIdRange(kr3); Assert.assertNotNull(state2); // can it be both, depending on the impl? Assert.assertTrue(DatastoreService.KeyRangeState.COLLISION == state2 || DatastoreService.KeyRangeState.CONTENTION == state2); }