All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.appengine.api.datastore.KeyRange Maven / Gradle / Ivy

Go to download

API for Google App Engine standard environment with some of the dependencies shaded (repackaged)

There is a newer version: 2.0.27
Show newest version
/*
 * Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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.google.appengine.api.datastore;

import java.io.Serializable;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * Represents a range of unique datastore identifiers from {@code getStart().getId()} to {@code
 * getEnd().getId()} inclusive. If an instance of this class is the result of a call to {@code
 * DatastoreService.allocateIds()}, the {@link Key Keys} returned by this instance have been
 * consumed in the datastore's id-space and are guaranteed never to be reused. 
* This class can be used to construct {@link Entity Entities} with {@link Key Keys} that have * specific id values without fear of the datastore creating new records with those same ids at a * later date. This can be helpful as part of a data migration or large bulk upload where you may * need to preserve existing ids and relationships between entities.
* This class is threadsafe but the {@link Iterator Iterators} returned by {@link #iterator()} are * not. * */ public final class KeyRange implements Iterable, Serializable { static final long serialVersionUID = 962890261927141064L; private final @Nullable Key parent; private final String kind; private final Key start; private final Key end; private final AppIdNamespace appIdNamespace; // Intentionally public to support users who want to allocate a range // and then reconstruct it later, perhaps in another request. public KeyRange(Key parent, String kind, long start, long end) { this(parent, kind, start, end, DatastoreApiHelper.getCurrentAppIdNamespace()); } KeyRange(Key parent, String kind, long start, long end, AppIdNamespace appIdNamespace) { if (parent != null && !parent.isComplete()) { throw new IllegalArgumentException("Invalid parent: not a complete key"); } if (kind == null || kind.isEmpty()) { throw new IllegalArgumentException("Invalid kind: cannot be null or empty"); } if (start < 1) { throw new IllegalArgumentException("Illegal start " + start + ": less than 1"); } if (end < start) { throw new IllegalArgumentException("Illegal end " + end + ": less than start " + start); } this.parent = parent; this.kind = kind; this.appIdNamespace = appIdNamespace; this.start = KeyFactory.createKey(parent, kind, start, appIdNamespace); this.end = KeyFactory.createKey(parent, kind, end, appIdNamespace); } /** * This constructor exists for frameworks (e.g. Google Web Toolkit) that require it for * serialization purposes. It should not be called explicitly. */ @SuppressWarnings({"unused", "nullness"}) private KeyRange() { parent = null; kind = null; start = null; end = null; appIdNamespace = null; } AppIdNamespace getAppIdNamespace() { return appIdNamespace; } /** @return The parent {@link Key} of the range. */ @Nullable Key getParent() { return parent; } /** @return The kind of the range. */ String getKind() { return kind; } /** Returns the first {@link Key} in the range. */ public Key getStart() { return start; } /** Returns the last {@link Key} in the range. */ public Key getEnd() { return end; } /** Returns the size of the range. */ public long getSize() { // range is inclusive so we add one to the difference return end.getId() - start.getId() + 1; } @Override public Iterator iterator() { return new IdRangeIterator(); } @Override public boolean equals(@Nullable Object obj) { if (!(obj instanceof KeyRange)) { return false; } KeyRange that = (KeyRange) obj; // only nee to compare start and end, since they contain parent and kind. return (this.start.equals(that.start) && this.end.equals(that.end)); } @Override public int hashCode() { return 31 * start.hashCode() + end.hashCode(); } /** * {@link Iterator} implementation that returns {@link Key Keys} in the range defined by the * enclosing {@link KeyRange}. */ private final class IdRangeIterator implements Iterator { private long next = start.getId(); @Override public boolean hasNext() { // range is inclusive return next <= end.getId(); } @Override public Key next() { if (!hasNext()) { throw new NoSuchElementException(); } return KeyFactory.createKey(parent, kind, next++, appIdNamespace); } @Override public void remove() { throw new UnsupportedOperationException(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy