// File: /workspace/github_c_makefile_star2_O0/coyove[P]chann/./lib/unqlite/unqlite.c
// Function: lhPageDefragment
static int lhPageDefragment(lhpage *pPage)
{
	lhash_kv_engine *pEngine = pPage->pHash;
	unsigned char *zTmp,*zPtr,*zEnd,*zPayload;
	lhcell *pCell;
	/* Get a temporary page from the pager. This opertaion never fail */
	zTmp = pEngine->pIo->xTmpPage(pEngine->pIo->pHandle);
	/* Move the target cells to the begining */
	pCell = pPage->pList;
	/* Write the slave page number */
	SyBigEndianPack64(&zTmp[2/*Offset of the first cell */+2/*Offset of the first free block */],pPage->sHdr.iSlave);
	zPtr = &zTmp[L_HASH_PAGE_HDR_SZ]; /* Offset to start writing from */
	zEnd = &zTmp[pEngine->iPageSize];
	pPage->sHdr.iOfft = 0; /* Offset of the first cell */
	for(;;){
		if( pCell == 0 ){
			/* No more cells */
			break;
		}
		if( pCell->pPage->pRaw->iPage == pPage->pRaw->iPage ){
			/* Cell payload if locally stored */
			zPayload = 0;
			if( pCell->iOvfl == 0 ){
				zPayload = &pCell->pPage->pRaw->zData[pCell->iStart + L_HASH_CELL_SZ];
			}
			/* Move the cell */
			pCell->iNext = pPage->sHdr.iOfft;
			pCell->iStart = (sxu16)(zPtr - zTmp); /* Offset where this cell start */
			pPage->sHdr.iOfft = pCell->iStart;
			/* Write the cell header */
			/* 4 byte hash number */
			SyBigEndianPack32(zPtr,pCell->nHash);
			zPtr += 4;
			/* 4 byte ley length */
			SyBigEndianPack32(zPtr,pCell->nKey);
			zPtr += 4;
			/* 8 byte data length */
			SyBigEndianPack64(zPtr,pCell->nData);
			zPtr += 8;
			/* 2 byte offset of the next cell */
			SyBigEndianPack16(zPtr,pCell->iNext);
			zPtr += 2;
			/* 8 byte overflow page number */
			SyBigEndianPack64(zPtr,pCell->iOvfl);
			zPtr += 8;
			if( zPayload ){
				/* Local payload */
				SyMemcpy((const void *)zPayload,zPtr,(sxu32)(pCell->nKey + pCell->nData));
				zPtr += pCell->nKey + pCell->nData;
			}
			if( zPtr >= zEnd ){
				/* Can't happen */
				break;
			}
		}
		/* Point to the next page */
		pCell = pCell->pNext;
	}
	/* Mark the free block */
	pPage->nFree = (sxu16)(zEnd - zPtr); /* Block length */
	if( pPage->nFree > 3 ){
		pPage->sHdr.iFree = (sxu16)(zPtr - zTmp); /* Offset of the free block */
		/* Mark the block */
		SyBigEndianPack16(zPtr,0); /* Offset of the next free block */
		SyBigEndianPack16(&zPtr[2],pPage->nFree); /* Block length */
	}else{
		/* Block of length less than 4 bytes are simply discarded */
		pPage->nFree = 0;
		pPage->sHdr.iFree = 0;
	}
	/* Reflect the change */
	SyBigEndianPack16(zTmp,pPage->sHdr.iOfft);     /* Offset of the first cell */
	SyBigEndianPack16(&zTmp[2],pPage->sHdr.iFree); /* Offset of the first free block */
	SyMemcpy((const void *)zTmp,pPage->pRaw->zData,pEngine->iPageSize);
	/* All done */
	return UNQLITE_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x68(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rcx
movq (%rcx), %rdi
callq *%rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rdi
addq $0x4, %rdi
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x61c60
movq -0x18(%rbp), %rax
addq $0xc, %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq 0x110(%rcx), %rcx
addq %rcx, %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movw $0x0, 0x10(%rax)
cmpq $0x0, -0x38(%rbp)
jne 0x64d2b
jmp 0x64ea3
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
cmpq 0x10(%rcx), %rax
jne 0x64e92
movq $0x0, -0x30(%rbp)
movq -0x38(%rbp), %rax
cmpq $0x0, 0x18(%rax)
jne 0x64d84
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq -0x38(%rbp), %rcx
movzwl 0x28(%rcx), %ecx
addl $0x1a, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movw 0x10(%rax), %cx
movq -0x38(%rbp), %rax
movw %cx, 0x10(%rax)
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
movw %ax, %cx
movq -0x38(%rbp), %rax
movw %cx, 0x28(%rax)
movq -0x38(%rbp), %rax
movw 0x28(%rax), %cx
movq -0x8(%rbp), %rax
movw %cx, 0x10(%rax)
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rax
movl (%rax), %esi
callq 0x61bf0
movq -0x20(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x4(%rax), %esi
callq 0x61bf0
movq -0x20(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x61c60
movq -0x20(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rax
movzwl 0x10(%rax), %esi
callq 0x63d00
movq -0x20(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x61c60
movq -0x20(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x64e84
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x38(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x38(%rbp), %rcx
addq 0x8(%rcx), %rax
movl %eax, %edx
callq 0x5d570
movq -0x38(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x38(%rbp), %rcx
addq 0x8(%rcx), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x28(%rbp), %rax
jb 0x64e90
jmp 0x64ea3
jmp 0x64e92
movq -0x38(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x38(%rbp)
jmp 0x64d1f
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rcx
subq %rcx, %rax
movw %ax, %cx
movq -0x8(%rbp), %rax
movw %cx, 0x5c(%rax)
movq -0x8(%rbp), %rax
movzwl 0x5c(%rax), %eax
cmpl $0x3, %eax
jle 0x64efe
movq -0x20(%rbp), %rax
movq -0x18(%rbp), %rcx
subq %rcx, %rax
movw %ax, %cx
movq -0x8(%rbp), %rax
movw %cx, 0x12(%rax)
movq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0x63d00
movq -0x20(%rbp), %rdi
addq $0x2, %rdi
movq -0x8(%rbp), %rax
movzwl 0x5c(%rax), %esi
callq 0x63d00
jmp 0x64f12
movq -0x8(%rbp), %rax
movw $0x0, 0x5c(%rax)
movq -0x8(%rbp), %rax
movw $0x0, 0x12(%rax)
movq -0x18(%rbp), %rdi
movq -0x8(%rbp), %rax
movzwl 0x10(%rax), %esi
callq 0x63d00
movq -0x18(%rbp), %rdi
addq $0x2, %rdi
movq -0x8(%rbp), %rax
movzwl 0x12(%rax), %esi
callq 0x63d00
movq -0x18(%rbp), %rdi
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rsi
movq -0x10(%rbp), %rax
movl 0x110(%rax), %edx
callq 0x5d570
xorl %eax, %eax
addq $0x40, %rsp
popq %rbp
retq
nop