Author: mturk Date: Tue Apr 14 14:28:09 2009 New Revision: 764789 URL: http://svn.apache.org/viewvc?rev=764789&view=rev Log: Add table utility code and test case
Added: commons/sandbox/runtime/trunk/src/main/native/include/acr_tables.h (with props) commons/sandbox/runtime/trunk/src/main/native/shared/tables.c (with props) Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in commons/sandbox/runtime/trunk/src/main/native/include/arch/unix/acr_arch.h commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h commons/sandbox/runtime/trunk/src/main/native/test/testcase.c commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=764789&r1=764788&r2=764789&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original) +++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Tue Apr 14 14:28:09 2009 @@ -68,7 +68,8 @@ $(SRCDIR)/shared/dbb.$(OBJ) \ $(SRCDIR)/shared/error.$(OBJ) \ $(SRCDIR)/shared/memory.$(OBJ) \ - $(SRCDIR)/shared/string.$(OBJ) + $(SRCDIR)/shared/string.$(OBJ) \ + $(SRCDIR)/shared/tables.$(OBJ) LINUX_OBJS= \ $(SRCDIR)/os/unix/main.$(OBJ) \ Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=764789&r1=764788&r2=764789&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original) +++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Tue Apr 14 14:28:09 2009 @@ -62,7 +62,8 @@ $(SRCDIR)/shared/dbb.$(OBJ) \ $(SRCDIR)/shared/error.$(OBJ) \ $(SRCDIR)/shared/memory.$(OBJ) \ - $(SRCDIR)/shared/string.$(OBJ) + $(SRCDIR)/shared/string.$(OBJ) \ + $(SRCDIR)/shared/tables.$(OBJ) WINDOWS_OBJS= \ $(SRCDIR)/os/win32/main.$(OBJ) \ Added: commons/sandbox/runtime/trunk/src/main/native/include/acr_tables.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_tables.h?rev=764789&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr_tables.h (added) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr_tables.h Tue Apr 14 14:28:09 2009 @@ -0,0 +1,191 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ACR_TABLES_H +#define _ACR_TABLES_H + +#include "acr.h" +#include <jni.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file acr_tables.h + * @brief + * + * ACR table functions and structures + * + */ + +#define ACR_TABLE_HASH_MASK 255 +#define ACR_TABLE_HASH_SIZE 256 + +/** the table abstract data type */ +typedef struct acr_table_t acr_table_t; + +typedef struct acr_array_t { + acr_size_t nelts; + acr_size_t nalloc; + acr_size_t esize; + char *elts; +} acr_array_t; + +/** + * Create array + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param nelts Initial number of elements in the array. + * @param esize Size of the each element + */ +ACR_DECLARE(acr_array_t *) ACR_ArrayMake(JNIEnv *env, const char *file, int line, + acr_size_t nelts, acr_size_t esize); + +/** + * Destroy the array and free used memory + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param arr Array to destroy. + */ +ACR_DECLARE(void) ACR_ArrayFree(JNIEnv *_E, const char *file, int line, + acr_array_t *arr); + +/** + * Add a new element to an array (as a first-in, last-out stack) + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param arr The array to add an element to. + */ +ACR_DECLARE(void *) ACR_ArrayPush(JNIEnv *_E, const char *file, int line, + acr_array_t *arr); + +/** + * Remove an element from an array (as a first-in, last-out stack) + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param arr The array to remove an element from. + * @return Location of the element in the array. + * @remark If there are no elements in the array, NULL is returned. + */ +ACR_DECLARE(void *) ACR_ArrayPop(acr_array_t *arr); + +/** + * Remove all elements from an array. + * @param arr The array to remove all elements from. + * @remark No memory is freed by this operation, + * but is available for reuse. + */ +ACR_DECLARE(void) ACR_ArrayClear(acr_array_t *arr); + +/** A helper macro for accessing a member of an ACR array. + * + * @param A the array + * @param I the index into the array to return + * @param T the type of the objects stored in the array + * + * @return the item at index i + */ +#define ACR_ARRAY_IDX(A,I,T) (((T *)(A)->elts)[I]) + +/** A helper macro for pushing elements into an ACR array. + * + * @param A the array + * @param T the type of the objects stored in the array + * + * @return the location where the new object should be placed + */ +#define ACR_ARRAY_PUSH(A,T) (*((T *)ACR_ArrayPush(_E,THROW_FMARK,A))) + +/** + * Create table + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param nelts Initial number of elements in the table. + */ +ACR_DECLARE(acr_table_t *) ACR_TableMake(JNIEnv *_E, const char *file, int line, + acr_size_t nelts); + +/** + * Destroy the table and free used memory + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param tbl Table to destroy. + */ +ACR_DECLARE(void) ACR_TableFree(JNIEnv *_E, const char *file, int line, + acr_table_t *tbl); + +/** + * Set the table key/data pair + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param t Table to use. + * @param key Key + * @param data Data + * @param dlen Data length + * @remark If key already exists in the table it's data will + * be overwritten. + */ +ACR_DECLARE(void) ACR_TableSet(JNIEnv *_E, const char *file, int line, + acr_table_t *t, const char *key, + const void *data, acr_size_t dlen); + +/** + * Add the key/data pair to the table + * @param env Current JNI environment. + * @param file Source file where the function was called + * @param line Source file line where the function was called + * @param t Table to use. + * @param key Key + * @param data Data + * @param dlen Data length + * @remark If the key alredy exists another instance will be added. + */ +ACR_DECLARE(void) ACR_TableAdd(JNIEnv *_E, const char *file, int line, + acr_table_t *t, const char *key, + const void *data, acr_size_t dlen); + +/** + * Get the data from the table + * @param t Table to use. + * @param key Key to get + * @param data Pointer where to store the data. Can be NULL + * @param dlen Pointer where to store the data length. Can be NULL + * @remark If the key was not found ACR_NOTFOUND is returned. In case + * it is found the data and dlen are set and ACR_SUCCESS is returned. + */ +ACR_DECLARE(int) ACR_TableGet(acr_table_t *t, const char *key, + void **data, acr_size_t *dlen); + +/** + * Get the internal table array + * @param tbl Table from which to get the array. + * @remark Returned array should be used only for traversing the data. + */ +ACR_DECLARE(const acr_array_t *) ACR_TableArray(acr_table_t *tbl); + +#ifdef __cplusplus +} +#endif + +#endif /* _ACR_TABLES_H */ Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr_tables.h ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/unix/acr_arch.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/unix/acr_arch.h?rev=764789&r1=764788&r2=764789&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/arch/unix/acr_arch.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/arch/unix/acr_arch.h Tue Apr 14 14:28:09 2009 @@ -23,6 +23,8 @@ extern "C" { #endif +#define ACR_INLINE inline + #define ACR_PLATFORM_CLASS_PATH ACR_CLASS_PATH "platform/unix/" #define ACR_JNI_PLATFORM_DECLARE(RT, CL, FN) \ JNIEXPORT RT JNICALL Java_org_apache_commons_runtime_platform_unix_##CL##_##FN Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=764789&r1=764788&r2=764789&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h Tue Apr 14 14:28:09 2009 @@ -179,6 +179,7 @@ extern "C" { #endif +#define ACR_INLINE __inline #define LOG_MSG_DOMAIN "ApacheCommonsRuntime" typedef enum { Added: commons/sandbox/runtime/trunk/src/main/native/shared/tables.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/tables.c?rev=764789&view=auto ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/shared/tables.c (added) +++ commons/sandbox/runtime/trunk/src/main/native/shared/tables.c Tue Apr 14 14:28:09 2009 @@ -0,0 +1,272 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "acr.h" +#include "acr_arch.h" +#include "acr_private.h" +#include "acr_error.h" +#include "acr_memory.h" +#include "acr_string.h" +#include "acr_vm.h" +#include "acr_tables.h" + +typedef struct table_entry_t table_entry_t; + +struct table_entry_t { + table_entry_t *next; + char *key; + void *data; + acr_size_t dlen; +}; + +struct acr_table_t { + /* Pointer to the array of table entries */ + acr_array_t a; + /* Table of hash buckets */ + table_entry_t *hash[ACR_TABLE_HASH_SIZE]; +}; + +ACR_DECLARE(acr_array_t *) ACR_ArrayMake(JNIEnv *_E, const char *file, int line, + acr_size_t nelts, acr_size_t esize) +{ + acr_array_t *arr = (acr_array_t *)ACR_Malloc(_E, file, line, + sizeof(acr_array_t)); + if (!arr) + return NULL; + if (nelts < 1) + nelts = 1; + if (esize < 1) + esize = 1; + arr->elts = (char *)ACR_Malloc(_E, file, line, nelts * esize); + if (!arr->elts) { + free(arr); + return NULL; + } + arr->nalloc = nelts; + arr->esize = esize; + arr->nelts = 0; + + return arr; +} + +ACR_DECLARE(void) ACR_ArrayFree(JNIEnv *_E, const char *file, int line, + acr_array_t *arr) +{ + if (arr) { + if (arr->elts) + free(arr->elts); + free(arr); + } + else { + ACR_ThrowException(_E, file, line, ACR_EX_ENULL, + ACR_EISNULL); + } +} + +ACR_DECLARE(void *) ACR_ArrayPush(JNIEnv *_E, const char *file, int line, + acr_array_t *arr) +{ + if (!arr) { + ACR_ThrowException(_E, file, line, ACR_EX_ENULL, + ACR_EISNULL); + return NULL; + } + if (!arr->elts) { + ACR_ThrowException(_E, file, line, ACR_EX_ENULL, + ACR_EISNULL); + return NULL; + } + if (arr->nelts == arr->nalloc) { + acr_size_t ns = (arr->nalloc << 1); + void *nd; + + if (!(nd = ACR_Malloc(_E, file, line, arr->esize * ns))) + return NULL; + memcpy(nd, arr->elts, arr->nalloc * arr->esize); + free(arr->elts); + arr->elts = nd; + arr->nalloc = ns; + } + + ++arr->nelts; + return arr->elts + (arr->esize * (arr->nelts - 1)); +} + +ACR_DECLARE(void *) ACR_ArrayPop(acr_array_t *arr) +{ + if (!arr || !arr->elts || !arr->nelts) { + return NULL; + } + else + return arr->elts + (arr->esize * (--arr->nelts)); +} + +ACR_DECLARE(void) ACR_ArrayClear(acr_array_t *arr) +{ + if (arr) { + arr->nelts = 0; + } +} + +static ACR_INLINE unsigned int times33hash(const char *key) +{ + const char *p; + unsigned int hash = 0; + for (p = key; *p; p++) { + hash = hash * 33 + *p; + } + return hash & ACR_TABLE_HASH_MASK; +} + +ACR_DECLARE(acr_table_t *) ACR_TableMake(JNIEnv *_E, const char *file, int line, + acr_size_t nelts) +{ + acr_table_t *tbl = (acr_table_t *)ACR_Calloc(_E, file, line, + sizeof(acr_table_t)); + if (!tbl) + return NULL; + if (nelts < 1) + nelts = 1; + tbl->a.elts = (char *)ACR_Malloc(_E, file, line, + nelts * sizeof(table_entry_t)); + if (!tbl->a.elts) { + free(tbl); + return NULL; + } + tbl->a.nalloc = nelts; + tbl->a.esize = sizeof(table_entry_t); + tbl->a.nelts = 0; + + return tbl; +} + +ACR_DECLARE(void) ACR_TableSet(JNIEnv *_E, const char *file, int line, + acr_table_t *t, const char *key, + const void *data, acr_size_t dlen) +{ + table_entry_t *e = NULL; + unsigned int hash; + + if (!key || !*key) { + ACR_ThrowException(_E, file, line, ACR_EX_ENULL, + ACR_EISNULL); + return; /* Skip empty and null strings */ + } + hash = times33hash(key); + + if (t->hash[hash]) { + /* + * This spot in the table is already in use. See if the current string + * has already been inserted, and if so, increment its count. + */ + for (e = t->hash[hash]; e; e = e->next) { + if (!strcmp(key, e->key)) + break; + } + } + if (e == NULL) { + e = (table_entry_t *)ACR_ArrayPush(_E, file, line, &(t->a)); + if (!e) { + /* The exception has already been thrown. + * Just bail out. + */ + return; + } + e->key = (char *)key; + /* Insert new bucket into the list */ + e->next = t->hash[hash]; + t->hash[hash] = e; + } + e->data = (void *)data; + e->dlen = dlen; +} + +ACR_DECLARE(void) ACR_TableAdd(JNIEnv *_E, const char *file, int line, + acr_table_t *t, const char *key, + const void *data, acr_size_t dlen) +{ + table_entry_t *e; + unsigned int hash; + + if (!key || !*key) { + ACR_ThrowException(_E, file, line, ACR_EX_ENULL, + ACR_EISNULL); + return; /* Skip empty and null strings */ + } + hash = times33hash(key); + + e = (table_entry_t *)ACR_ArrayPush(_E, file, line, &(t->a)); + if (!e) { + /* The exception has already been thrown. + * Just bail out. + */ + return; + } + e->key = (char *)key; + e->data = (void *)data; + e->dlen = dlen; + /* Insert new bucket into the list */ + e->next = t->hash[hash]; + t->hash[hash] = e; +} + +ACR_DECLARE(int) ACR_TableGet(acr_table_t *t, const char *key, + void **data, acr_size_t *dlen) +{ + table_entry_t *e = NULL; + unsigned int hash; + + if (!key || !*key) { + return ACR_EINVAL; /* Skip empty and null strings */ + } + hash = times33hash(key); + + if (t->hash[hash]) { + for (e = t->hash[hash]; e; e = e->next) { + if (!strcmp(key, e->key)) { + if (data) + *data = e->data; + if (dlen) + *dlen = e->dlen; + + return ACR_SUCCESS; + } + } + } + return ACR_NOTFOUND; +} + +ACR_DECLARE(void) ACR_TableFree(JNIEnv *_E, const char *file, int line, + acr_table_t *tbl) +{ + if (tbl) { + if (tbl->a.elts) + free(tbl->a.elts); + free(tbl); + } + else { + ACR_ThrowException(_E, file, line, ACR_EX_ENULL, + ACR_EISNULL); + } +} + +ACR_DECLARE(const acr_array_t *) ACR_TableArray(acr_table_t *tbl) +{ + if (tbl) + return &(tbl->a); + else + return NULL; +} Propchange: commons/sandbox/runtime/trunk/src/main/native/shared/tables.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/sandbox/runtime/trunk/src/main/native/test/testcase.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/test/testcase.c?rev=764789&r1=764788&r2=764789&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/test/testcase.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/test/testcase.c Tue Apr 14 14:28:09 2009 @@ -20,6 +20,7 @@ #include "acr_error.h" #include "acr_string.h" #include "acr_memory.h" +#include "acr_tables.h" #include "acr_vm.h" @@ -84,3 +85,48 @@ CSTR_RELEASE(s); return l; } + +ACR_JNI_EXPORT_DECLARE(jint, TestPrivate, test007)(ACR_JNISTDARGS, jint d) +{ + acr_array_t *a; + int i; + + a = ACR_ArrayMake(_E, THROW_FMARK, 0, sizeof(int)); + for (i = 0; i < 10; i++) { + ACR_ARRAY_PUSH(a, int) = i; + } + for (i = 0; i < 10; i++) { + if (i != (ACR_ARRAY_IDX(a, i, int))) + break; + } + ACR_ArrayFree(_E, THROW_FMARK, a); + return i; +} + +ACR_JNI_EXPORT_DECLARE(jint, TestPrivate, test008)(ACR_JNISTDARGS, jstring s) +{ + acr_table_t *t; + void *d; + acr_size_t l; + jint rc = 0; + CSTR_GETCHAR(s); + + t = ACR_TableMake(_E, THROW_FMARK, 1); + ACR_TableSet(_E, THROW_FMARK, t, J2S(s), J2S(s), 0); + ACR_TableSet(_E, THROW_FMARK, t, J2S(s), J2S(s), 1); + + if (ACR_TableGet(t, J2S(s), &d, &l) == ACR_SUCCESS) { + if (!strcmp(J2S(s), (const char *)d) && l == 1) + rc = 1; + } + if (rc) { + const acr_array_t *a; + ACR_TableAdd(_E, THROW_FMARK, t, J2S(s), J2S(s), 2); + a = ACR_TableArray(t); + if (a->nelts != 2) + rc = 0; + } + ACR_TableFree(_E, THROW_FMARK, t); + CSTR_RELEASE(s); + return rc; +} Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java?rev=764789&r1=764788&r2=764789&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestPrivate.java Tue Apr 14 14:28:09 2009 @@ -46,6 +46,8 @@ private static native int test004(int d); private static native int test005(String msg); private static native int test006(String msg); + private static native int test007(int d); + private static native int test008(String msg); protected void setUp() @@ -138,4 +140,18 @@ assertEquals("Length", 6, i); } + public void testArray() + throws Exception + { + int i = test007(0); + assertEquals("Count", 10, i); + } + + public void testTable() + throws Exception + { + int i = test008("Foo"); + assertEquals("Result", 1, i); + } + }