@Override
	public Iterator<Map.Entry<byte[], byte[]>> iterator(){
		return new Iterator<Map.Entry<byte[],byte[]>>() {
			BucketView nextBucket = new BucketView(0),
			           prevBucket = null;
			int nextIdx = 0, nextSubIdx = -1, prevSubIdx = -1;
			{
				advance();
			}
			private void advance(){
				prevSubIdx = nextSubIdx; prevBucket = nextBucket;
				
				while(true){
					nextSubIdx++;
					if(nextSubIdx >= recordsPerBucket){
						nextSubIdx = 0;
						nextBucket = nextBucket.nextBucket();
					}
					if(nextBucket == null){
						nextIdx++;
						if(nextIdx >= tableLength) return;
						nextBucket = new BucketView(nextIdx);
					}
					if(!nextBucket.getPointer(nextSubIdx).isWritable()) return;
				}
			}
			@Override
			public boolean hasNext() {
				return nextBucket != null;
			}
			@Override
			public Entry<byte[], byte[]> next() {
				if(! hasNext()) throw new NoSuchElementException();
				final BucketDiskMapEntry out = new BucketDiskMapEntry(nextBucket, nextSubIdx);
				advance();
				return out;
			}
			@Override
			public void remove() {
				if(prevBucket == null) throw new IllegalStateException();
				prevBucket.writeRecord(RecordPtr.DELETED, prevSubIdx);
				BucketDiskMap.this.size.decrementAndGet();
			}
		};
	}