@Override public <T extends MemorySegment> void release(Collection<T> segments) { // sanity checks if (segments == null) { return; } // -------------------- BEGIN CRITICAL SECTION ------------------- synchronized (this.lock) { if (this.isShutDown) { throw new IllegalStateException("Memory manager has been shut down."); } final Iterator<T> segmentsIterator = segments.iterator(); AbstractInvokable lastOwner = null; Set<DefaultMemorySegment> segsForOwner = null; // go over all segments while (segmentsIterator.hasNext()) { final MemorySegment seg = segmentsIterator.next(); if (seg.isFreed()) { continue; } final DefaultMemorySegment defSeg = (DefaultMemorySegment) seg; final AbstractInvokable owner = defSeg.owner; try { // get the list of segments by this owner only if it is a different owner than for // the previous one (or it is the first segment) if (lastOwner != owner) { lastOwner = owner; segsForOwner = this.allocatedSegments.get(owner); } // remove the segment from the list if (segsForOwner != null) { segsForOwner.remove(defSeg); if (segsForOwner.isEmpty()) { this.allocatedSegments.remove(owner); } } } catch (Throwable t) { LOG.error("Error removing book-keeping reference to allocated memory segment.", t); } finally { // release the memory in any case byte[] buffer = defSeg.destroy(); this.freeSegments.add(buffer); } } segments.clear(); } // -------------------- END CRITICAL SECTION ------------------- }
@Override public void copyNormalizedKey(MemorySegment target, int offset, int len) { if (len == 1) { // default case, full normalized key. need to explicitly convert to int to // avoid false results due to implicit type conversion to int when subtracting // the min byte value int highByte = this.value & 0xff; highByte -= Byte.MIN_VALUE; target.put(offset, (byte) highByte); } else if (len <= 0) { } else { int highByte = this.value & 0xff; highByte -= Byte.MIN_VALUE; target.put(offset, (byte) highByte); for (int i = 1; i < len; i++) { target.put(offset + i, (byte) 0); } } }
@Override public void release(MemorySegment segment) { // check if segment is null or has already been freed if (segment == null || segment.isFreed() || !(segment instanceof DefaultMemorySegment)) { return; } final DefaultMemorySegment defSeg = (DefaultMemorySegment) segment; final AbstractInvokable owner = defSeg.owner; // -------------------- BEGIN CRITICAL SECTION ------------------- synchronized (this.lock) { if (this.isShutDown) { throw new IllegalStateException("Memory manager has been shut down."); } // remove the reference in the map for the owner try { Set<DefaultMemorySegment> segsForOwner = this.allocatedSegments.get(owner); if (segsForOwner != null) { segsForOwner.remove(defSeg); if (segsForOwner.isEmpty()) { this.allocatedSegments.remove(owner); } } } catch (Throwable t) { LOG.error("Error removing book-keeping reference to allocated memory segment.", t); } finally { // release the memory in any case byte[] buffer = defSeg.destroy(); this.freeSegments.add(buffer); } } // -------------------- END CRITICAL SECTION ------------------- }
@Override public void putNormalizedKey(String record, MemorySegment target, int offset, int len) { ; final int limit = offset + len; final int end = record.length(); int pos = 0; while (pos < end && offset < limit) { char c = record.charAt(pos++); if (c < HIGH_BIT) { target.put(offset++, (byte) c); } else if (c < HIGH_BIT2) { target.put(offset++, (byte) ((c >>> 7) | HIGH_BIT)); if (offset < limit) target.put(offset++, (byte) c); } else { target.put(offset++, (byte) ((c >>> 10) | HIGH_BIT2_MASK)); if (offset < limit) target.put(offset++, (byte) (c >>> 2)); if (offset < limit) target.put(offset++, (byte) c); } } while (offset < limit) { target.put(offset++, (byte) 0); } }