/** * Calculate the insertKey that places a CrawlURI in the desired spot. First bytes are always * classKey (usu. host) based -- ensuring grouping by host -- terminated by a zero byte. Then 8 * bytes of data ensuring desired ordering within that 'queue' are used. The first byte of these 8 * is priority -- allowing 'immediate' and 'soon' items to sort above regular. Next 1 byte is * 'precedence'. Last 6 bytes are ordinal serial number, ensuring earlier-discovered URIs sort * before later. * * <p>NOTE: Dangers here are: (1) priorities or precedences over 2^7 (signed byte comparison) (2) * ordinals over 2^48 * * <p>Package access & static for testing purposes. * * @param curi * @return a DatabaseEntry key for the CrawlURI */ static DatabaseEntry calculateInsertKey(CrawlURI curi) { byte[] classKeyBytes = null; int len = 0; classKeyBytes = curi.getClassKey().getBytes(Charsets.UTF_8); len = classKeyBytes.length; byte[] keyData = new byte[len + 9]; System.arraycopy(classKeyBytes, 0, keyData, 0, len); keyData[len] = 0; long ordinalPlus = curi.getOrdinal() & 0x0000FFFFFFFFFFFFL; ordinalPlus = ((long) curi.getSchedulingDirective() << 56) | ordinalPlus; long precedence = Math.min(curi.getPrecedence(), 127); ordinalPlus = (((precedence) & 0xFFL) << 48) | ordinalPlus; ArchiveUtils.longIntoByteArray(ordinalPlus, keyData, len + 1); return new DatabaseEntry(keyData); }