private void checkOpen() { if (closed) { throw DataUtils.newIllegalStateException(DataUtils.ERROR_CLOSED, "This store is closed", panicException); } }
/** * Check whether this transaction is open or prepared. */ void checkNotClosed() { if (status == STATUS_CLOSED) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_CLOSED, "Transaction is closed"); } }
@Override public final Object read(ByteBuffer buff) { throw DataUtils.newIllegalStateException(DataUtils.ERROR_INTERNAL, "Internal error"); }
/** * Flush all changes. */ public void sync() { try { file.force(true); } catch (IOException e) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_WRITING_FAILED, "Could not sync file {0}", fileName, e); } }
/** * Add an element at the end. * * @param obj the element */ public synchronized void add(K obj) { if (obj == null) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_INTERNAL, "adding null value to list"); } int len = array.length; array = Arrays.copyOf(array, len + 1); array[len] = obj; }
/** * Get the block. * * @param key the key * @return the block */ byte[] getBlock(long key) { byte[] data = map.get(key); if (data == null) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_BLOCK_NOT_FOUND, "Block {0} not found", key); } return data; }
/** * Parse an unsigned, hex long. * * @param x the string * @return the parsed value * @throws IllegalStateException if parsing fails */ public static int parseHexInt(String x) { try { // avoid problems with overflow // in Java 8, we can use Integer.parseLong(x, 16); return (int) Long.parseLong(x, 16); } catch (NumberFormatException e) { throw newIllegalStateException(ERROR_FILE_CORRUPT, "Error parsing the value {0}", x, e); } }
/** * Truncate the file. * * @param size the new file size */ public void truncate(long size) { try { writeCount.incrementAndGet(); file.truncate(size); fileSize = Math.min(fileSize, size); } catch (IOException e) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_WRITING_FAILED, "Could not truncate file {0} to size {1}", fileName, size, e); } }
@Override public void free(long pos, int length) { freeSpace.free(pos, length); ByteBuffer buff = memory.remove(pos); if (buff == null) { // nothing was written (just allocated) } else if (buff.remaining() != length) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_READING_FAILED, "Partial remove is not supported at position {0}", pos); } }
/** * Write to a file channel. * * @param file the file channel * @param pos the absolute position within the file * @param src the source buffer */ public static void writeFully(FileChannel file, long pos, ByteBuffer src) { try { int off = 0; do { int len = file.write(src, pos + off); off += len; } while (src.remaining() > 0); } catch (IOException e) { throw newIllegalStateException( ERROR_WRITING_FAILED, "Writing to {0} failed; length {1} at {2}", file, src.remaining(), pos, e); } }
/** * Parse an unsigned, hex long. * * @param x the string * @return the parsed value * @throws IllegalStateException if parsing fails */ public static long parseHexLong(String x) { try { if (x.length() == 16) { // avoid problems with overflow // in Java 8, this special case is not needed return (Long.parseLong(x.substring(0, 8), 16) << 32) | Long.parseLong(x.substring(8, 16), 16); } return Long.parseLong(x, 16); } catch (NumberFormatException e) { throw newIllegalStateException(ERROR_FILE_CORRUPT, "Error parsing the value {0}", x, e); } }
@Override public ByteBuffer readFully(long pos, int len) { Entry<Long, ByteBuffer> memEntry = memory.floorEntry(pos); if (memEntry == null) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_READING_FAILED, "Could not read from position {0}", pos); } readCount.incrementAndGet(); readBytes.addAndGet(len); ByteBuffer buff = memEntry.getValue(); ByteBuffer read = buff.duplicate(); int offset = (int) (pos - memEntry.getKey()); read.position(offset); read.limit(len + offset); return read.slice(); }
/** * Close this store. */ public void close() { try { if (fileLock != null) { fileLock.release(); fileLock = null; } file.close(); freeSpace.clear(); } catch (Exception e) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_WRITING_FAILED, "Closing failed for file {0}", fileName, e); } finally { file = null; } }
private void loadChunkMeta() { // load the chunk metadata: we can load in any order, // because loading chunk metadata might recursively load another chunk for (Iterator<String> it = meta.keyIterator("chunk."); it.hasNext();) { String s = it.next(); if (!s.startsWith("chunk.")) { break; } s = meta.get(s); Chunk c = Chunk.fromString(s); if (chunks.putIfAbsent(c.id, c) == null) { if (c.block == Long.MAX_VALUE) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_FILE_CORRUPT, "Chunk {0} is invalid", c.id); } } } }
/** * Get the chunk for the given position. * * @param pos the position * @return the chunk */ private Chunk getChunk(long pos) { Chunk c = getChunkIfFound(pos); if (c == null) { int chunkId = DataUtils.getPageChunkId(pos); throw DataUtils.newIllegalStateException( DataUtils.ERROR_FILE_CORRUPT, "Chunk {0} not found", chunkId); } return c; }
/** * This method is called before writing to the map. The default * implementation checks whether writing is allowed, and tries * to detect concurrent modification. * * @throws UnsupportedOperationException if the map is read-only, * or if another thread is concurrently writing */ protected void beforeWrite() { if (closed) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_CLOSED, "This map is closed"); } if (readOnly) { throw DataUtils.newUnsupportedOperationException( "This map is read-only"); } store.beforeWrite(this); }
/** * Remove a log entry. * * @param t the transaction * @param logId the log id */ public void logUndo(Transaction t, long logId) { Long undoKey = getOperationId(t.getId(), logId); rwLock.writeLock().lock(); try { Object[] old = undoLog.remove(undoKey); if (old == null) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_TRANSACTION_ILLEGAL_STATE, "Transaction {0} was concurrently rolled back", t.getId()); } } finally { rwLock.writeLock().unlock(); } }
private V set(K key, V value) { transaction.checkNotClosed(); V old = get(key); boolean ok = trySet(key, value, false); if (ok) { return old; } throw DataUtils.newIllegalStateException( DataUtils.ERROR_TRANSACTION_LOCKED, "Entry is locked"); }
/** * Unlink the children recursively after all data is written. */ void writeEnd() { if (isLeaf()) { return; } int len = children.length; for (int i = 0; i < len; i++) { PageReference ref = children[i]; if (ref.page != null) { if (ref.page.getPos() == 0) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_INTERNAL, "Page not written"); } ref.page.writeEnd(); children[i] = new PageReference(null, ref.pos, ref.count); } } }
/** * Write the chunk header. * * @param buff the target buffer * @param minLength the minimum length */ void writeChunkHeader(WriteBuffer buff, int minLength) { long pos = buff.position(); buff.put(asString().getBytes(StandardCharsets.ISO_8859_1)); while (buff.position() - pos < minLength - 1) { buff.put((byte) ' '); } if (minLength != 0 && buff.position() > minLength) { throw DataUtils.newIllegalStateException( DataUtils.ERROR_INTERNAL, "Chunk metadata too long"); } buff.put((byte) '\n'); }