docs: private void insertBucketEntryFromStart(MemorySegment bucket, int bucketInSegmentPos,
  											int hashCode, long pointer, int partitionNumber)
  	throws IOException
  	{
  		boolean checkForResize = false;
  		// find the position to put the hash code and pointer
  		final int count = bucket.getInt(bucketInSegmentPos + HEADER_COUNT_OFFSET);
  		if (count < NUM_ENTRIES_PER_BUCKET) {
  			// we are good in our current bucket, put the values
  			bucket.putInt(bucketInSegmentPos + BUCKET_HEADER_LENGTH + (count * HASH_CODE_LEN), hashCode);	// hash code
  			bucket.putLong(bucketInSegmentPos + BUCKET_POINTER_START_OFFSET + (count * POINTER_LEN), pointer); // pointer
  			bucket.putInt(bucketInSegmentPos + HEADER_COUNT_OFFSET, count + 1); // update count
  		}
  		else {
  			// we need to go to the overflow buckets
  			final InMemoryPartition<T> p = this.partitions.get(partitionNumber);
  			
  			final long originalForwardPointer = bucket.getLong(bucketInSegmentPos + HEADER_FORWARD_OFFSET);
  			final long forwardForNewBucket;
  			
  			if (originalForwardPointer != BUCKET_FORWARD_POINTER_NOT_SET) {
  				
  				// forward pointer set
  				final int overflowSegNum = (int) (originalForwardPointer >>> 32);
  				final int segOffset = (int) originalForwardPointer;
  				final MemorySegment seg = p.overflowSegments[overflowSegNum];
  				
  				final int obCount = seg.getInt(segOffset + HEADER_COUNT_OFFSET);
  				
  				// check if there is space in this overflow bucket
  				if (obCount < NUM_ENTRIES_PER_BUCKET) {
  					// space in this bucket and we are done
  					seg.putInt(segOffset + BUCKET_HEADER_LENGTH + (obCount * HASH_CODE_LEN), hashCode);	// hash code
  					seg.putLong(segOffset + BUCKET_POINTER_START_OFFSET + (obCount * POINTER_LEN), pointer); // pointer
  					seg.putInt(segOffset + HEADER_COUNT_OFFSET, obCount + 1); // update count
  					return;
  				} else {
  					// no space here, we need a new bucket. this current overflow bucket will be the
  					// target of the new overflow bucket
  					forwardForNewBucket = originalForwardPointer;
  				}
  			} else {
  				// no overflow bucket yet, so we need a first one
  				forwardForNewBucket = BUCKET_FORWARD_POINTER_NOT_SET;
  			}
  			
  			// we need a new overflow bucket
  			MemorySegment overflowSeg;
  			final int overflowBucketNum;
  			final int overflowBucketOffset;
  			
  			// first, see if there is space for an overflow bucket remaining in the last overflow segment
  			if (p.nextOverflowBucket == 0) {
  				// no space left in last bucket, or no bucket yet, so create an overflow segment
  				overflowSeg = getNextBuffer();
  				overflowBucketOffset = 0;
  				overflowBucketNum = p.numOverflowSegments;
  				
  				// add the new overflow segment
  				if (p.overflowSegments.length <= p.numOverflowSegments) {
  					MemorySegment[] newSegsArray = new MemorySegment[p.overflowSegments.length * 2];
  					System.arraycopy(p.overflowSegments, 0, newSegsArray, 0, p.overflowSegments.length);
  					p.overflowSegments = newSegsArray;
  				}
  				p.overflowSegments[p.numOverflowSegments] = overflowSeg;
  				p.numOverflowSegments++;
  				checkForResize = true;
  			} else {
  				// there is space in the last overflow bucket
  				overflowBucketNum = p.numOverflowSegments - 1;
  				overflowSeg = p.overflowSegments[overflowBucketNum];
  				overflowBucketOffset = p.nextOverflowBucket << NUM_INTRA_BUCKET_BITS;
  			}
  			
  			// next overflow bucket is one ahead. if the segment is full, the next will be at the beginning
  			// of a new segment
  			p.nextOverflowBucket = (p.nextOverflowBucket == this.bucketsPerSegmentMask ? 0 : p.nextOverflowBucket + 1);
  			
  			// insert the new overflow bucket in the chain of buckets
  			// 1) set the old forward pointer
  			// 2) let the bucket in the main table point to this one
  			overflowSeg.putLong(overflowBucketOffset + HEADER_FORWARD_OFFSET, forwardForNewBucket);
  			final long pointerToNewBucket = (((long) overflowBucketNum) << 32) | ((long) overflowBucketOffset);
  			bucket.putLong(bucketInSegmentPos + HEADER_FORWARD_OFFSET, pointerToNewBucket);
  			
  			// finally, insert the values into the overflow buckets
  			overflowSeg.putInt(overflowBucketOffset + BUCKET_HEADER_LENGTH, hashCode); // hash code
  			overflowSeg.putLong(overflowBucketOffset + BUCKET_POINTER_START_OFFSET, pointer); // pointer
  			
  			// set the count to one
  			overflowSeg.putInt(overflowBucketOffset + HEADER_COUNT_OFFSET, 1);
  			
  			if (checkForResize && !this.isResizing) {
  				// check if we should resize buckets
  				if (this.buckets.length <= getOverflowSegmentCount()) {
  					resizeHashTable();
  				}
  			}
  		}
  	}