/*===========================================================================
*
*                            PUBLIC DOMAIN NOTICE
*               National Center for Biotechnology Information
*
*  This software/database is a "United States Government Work" under the
*  terms of the United States Copyright Act.  It was written as part of
*  the author's official duties as a United States Government employee and
*  thus cannot be copyrighted.  This software/database is freely available
*  to the public for use. The National Library of Medicine and the U.S.
*  Government have not placed any restriction on its use or reproduction.
*
*  Although all reasonable efforts have been taken to ensure the accuracy
*  and reliability of the software and data, the NLM and the U.S.
*  Government do not and cannot warrant the performance or results that
*  may be obtained by using this software or data. The NLM and the U.S.
*  Government disclaim all warranties, express or implied, including
*  warranties of performance, merchantability or fitness for any particular
*  purpose.
*
*  Please cite the author in any work or product based on this material.
*
* ===========================================================================
*
*/
#include <vdb/extern.h>
#include <vdb/xform.h>
#include <arch-impl.h>
#include <klib/data-buffer.h>
#include <klib/rc.h>
#include <sysalloc.h>

#include <stdlib.h>
#include <assert.h>
#include <string.h>

static
rc_t CC subtract_int64_t ( void *self, const VXformInfo *info,
    int64_t row_id, VRowResult *rslt,
    uint32_t argc, const VRowData argv [] )
{
    rc_t rc;
    uint32_t i;
    int64_t *dst;
    const int64_t *src = argv [ 0 ] . u . data . base;
    uint64_t elem_count = argv [ 0 ] . u . data . elem_count;

    assert ( rslt -> data -> elem_bits == 64 );
    rc = KDataBufferResize ( rslt -> data, elem_count );
    if ( rc != 0 )
        return rc;

    dst = rslt -> data -> base;
    rslt -> elem_count = elem_count;

    /* while this function is typically used on single-element rows,
       we advertise taking rows of any length... */
    for ( i = 0, src += argv [ 0 ] . u . data . first_elem; i < elem_count; ++ i )
        dst [ i ] = src [ i ] - row_id;

    return 0;
}


/* subtract_row_id
 *  return the difference between input and current row id
 *
 *  "in" [ DATA ]
 *
 * SYNOPSIS:
 *  predicts that the integer data in "in" will be related to
 *  the corresponding row-id, and subtracts off the latter.
 *  for serially generated ids, this will produce a constant
 *  difference that can be stored as a static column.
 */
VTRANSFACT_IMPL ( vdb_subtract_row_id, 1, 0, 0 ) ( const void *fself, const VXfactInfo *info,
    VFuncDesc *rslt, const VFactoryParams *cp, const VFunctionParams *dp )
{
    /* version 1.0 operates on I64 input */
    rslt -> u . ndf = subtract_int64_t;
    rslt -> variant = vftNonDetRow;
    return 0;
}
