hdfs.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "hdfs.h"
  19. #include "hdfsJniHelper.h"
  20. /* Some frequently used Java paths */
  21. #define HADOOP_CONF "org/apache/hadoop/conf/Configuration"
  22. #define HADOOP_PATH "org/apache/hadoop/fs/Path"
  23. #define HADOOP_LOCALFS "org/apache/hadoop/fs/LocalFileSystem"
  24. #define HADOOP_FS "org/apache/hadoop/fs/FileSystem"
  25. #define HADOOP_DFS "org/apache/hadoop/dfs/DistributedFileSystem"
  26. #define HADOOP_ISTRM "org/apache/hadoop/fs/FSDataInputStream"
  27. #define HADOOP_OSTRM "org/apache/hadoop/fs/FSDataOutputStream"
  28. #define JAVA_NET_ISA "java/net/InetSocketAddress"
  29. #define JAVA_NET_URI "java/net/URI"
  30. /* Macros for constructing method signatures */
  31. #define JPARAM(X) "L" X ";"
  32. #define JARRPARAM(X) "[L" X ";"
  33. #define JMETHOD1(X, R) "(" X ")" R
  34. #define JMETHOD2(X, Y, R) "(" X Y ")" R
  35. /**
  36. * hdfsJniEnv: A wrapper struct to be used as 'value'
  37. * while saving thread -> JNIEnv* mappings
  38. */
  39. typedef struct
  40. {
  41. JNIEnv* env;
  42. } hdfsJniEnv;
  43. /**
  44. * Helper function to destroy a local reference of java.lang.Object
  45. * @param env: The JNIEnv pointer.
  46. * @param jFile: The local reference of java.lang.Object object
  47. * @return None.
  48. */
  49. static void destroyLocalReference(JNIEnv *env, jobject jObject)
  50. {
  51. if (jObject)
  52. (*env)->DeleteLocalRef(env, jObject);
  53. }
  54. /**
  55. * Helper function to create a org.apache.hadoop.fs.Path object.
  56. * @param env: The JNIEnv pointer.
  57. * @param path: The file-path for which to construct org.apache.hadoop.fs.Path
  58. * object.
  59. * @return Returns a jobject on success and NULL on error.
  60. */
  61. static jobject constructNewObjectOfPath(JNIEnv *env, const char *path)
  62. {
  63. //Construct a java.lang.String object
  64. jstring jPathString = (*env)->NewStringUTF(env, path);
  65. //Construct the org.apache.hadoop.fs.Path object
  66. jobject jPath =
  67. constructNewObjectOfClass(env, "org/apache/hadoop/fs/Path",
  68. "(Ljava/lang/String;)V", jPathString);
  69. if (jPath == NULL) {
  70. fprintf(stderr, "Can't construct instance of class "
  71. "org.apache.hadoop.fs.Path for %s\n", path);
  72. errno = EINTERNAL;
  73. return NULL;
  74. }
  75. // Destroy the local reference to the java.lang.String object
  76. destroyLocalReference(env, jPathString);
  77. return jPath;
  78. }
  79. hdfsFS hdfsConnect(const char* host, tPort port)
  80. {
  81. // JAVA EQUIVALENT:
  82. // FileSystem fs = FileSystem.get(new Configuration());
  83. // return fs;
  84. JNIEnv *env = 0;
  85. jobject jConfiguration = NULL;
  86. jobject jFS = NULL;
  87. jobject jURI = NULL;
  88. jstring jURIString = NULL;
  89. jvalue jVal;
  90. char *cURI = 0;
  91. jobject gFsRef = NULL;
  92. //Get the JNIEnv* corresponding to current thread
  93. env = getJNIEnv();
  94. //Create the org.apache.hadoop.conf.Configuration object
  95. jConfiguration =
  96. constructNewObjectOfClass(env, HADOOP_CONF, "()V");
  97. if (jConfiguration == NULL) {
  98. fprintf(stderr, "Can't construct instance of class "
  99. "org.apache.hadoop.conf.Configuration\n");
  100. errno = EINTERNAL;
  101. return NULL;
  102. }
  103. //Check what type of FileSystem the caller wants...
  104. if (host == NULL) {
  105. // fs = FileSytem::getLocal(conf);
  106. if (invokeMethod(env, &jVal, STATIC, NULL, HADOOP_FS, "getLocal",
  107. JMETHOD1(JPARAM(HADOOP_CONF),
  108. JPARAM(HADOOP_LOCALFS)),
  109. jConfiguration) != 0) {
  110. fprintf(stderr, "Call to org.apache.hadoop.fs."
  111. "FileSystem::getLocal failed!\n");
  112. errno = EINTERNAL;
  113. goto done;
  114. }
  115. jFS = jVal.l;
  116. }
  117. else if (!strcmp(host, "default") && port == 0) {
  118. //fs = FileSystem::get(conf);
  119. if (invokeMethod(env, &jVal, STATIC, NULL,
  120. HADOOP_FS, "get",
  121. JMETHOD1(JPARAM(HADOOP_CONF),
  122. JPARAM(HADOOP_FS)),
  123. jConfiguration) != 0) {
  124. fprintf(stderr, "Call to org.apache.hadoop.fs."
  125. "FileSystem::get failed!\n");
  126. errno = EINTERNAL;
  127. goto done;
  128. }
  129. jFS = jVal.l;
  130. }
  131. else {
  132. // fs = FileSystem::get(URI, conf);
  133. cURI = malloc(strlen(host)+16);
  134. sprintf(cURI, "hdfs://%s:%d", host, (int)(port));
  135. jURIString = (*env)->NewStringUTF(env, cURI);
  136. if (invokeMethod(env, &jVal, STATIC, NULL, JAVA_NET_URI,
  137. "create", "(Ljava/lang/String;)Ljava/net/URI;",
  138. jURIString) != 0) {
  139. fprintf(stderr, "Call to java.net.URI::create failed!\n");
  140. errno = EINTERNAL;
  141. goto done;
  142. }
  143. jURI = jVal.l;
  144. if (invokeMethod(env, &jVal, STATIC, NULL, HADOOP_FS, "get",
  145. JMETHOD2(JPARAM(JAVA_NET_URI),
  146. JPARAM(HADOOP_CONF), JPARAM(HADOOP_FS)),
  147. jURI, jConfiguration) != 0) {
  148. fprintf(stderr, "Call to org.apache.hadoop.fs."
  149. "FileSystem::get(URI, Configuration) failed!\n");
  150. errno = EINTERNAL;
  151. goto done;
  152. }
  153. jFS = jVal.l;
  154. }
  155. done:
  156. // Release unnecessary local references
  157. destroyLocalReference(env, jConfiguration);
  158. destroyLocalReference(env, jURIString);
  159. destroyLocalReference(env, jURI);
  160. if (cURI) free(cURI);
  161. /* Create a global reference for this fs */
  162. if (jFS) {
  163. gFsRef = (*env)->NewGlobalRef(env, jFS);
  164. destroyLocalReference(env, jFS);
  165. }
  166. return gFsRef;
  167. }
  168. int hdfsDisconnect(hdfsFS fs)
  169. {
  170. // JAVA EQUIVALENT:
  171. // fs.close()
  172. //Get the JNIEnv* corresponding to current thread
  173. JNIEnv* env = getJNIEnv();
  174. //Parameters
  175. jobject jFS = (jobject)fs;
  176. //Sanity check
  177. if (fs == NULL) {
  178. errno = EBADF;
  179. return -1;
  180. }
  181. if (invokeMethod(env, NULL, INSTANCE, jFS, HADOOP_FS,
  182. "close", "()V") != 0) {
  183. fprintf(stderr, "Call to FileSystem::close failed!\n");
  184. errno = EINTERNAL;
  185. return -1;
  186. }
  187. //Release unnecessary references
  188. (*env)->DeleteGlobalRef(env, fs);
  189. return 0;
  190. }
  191. hdfsFile hdfsOpenFile(hdfsFS fs, const char* path, int flags,
  192. int bufferSize, short replication, tSize blockSize)
  193. {
  194. /*
  195. JAVA EQUIVALENT:
  196. File f = new File(path);
  197. FSData{Input|Output}Stream f{is|os} = fs.create(f);
  198. return f{is|os};
  199. */
  200. /* Get the JNIEnv* corresponding to current thread */
  201. JNIEnv* env = getJNIEnv();
  202. jobject jFS = (jobject)fs;
  203. /* The hadoop java api/signature */
  204. const char* method = (flags == O_RDONLY) ? "open" : "create";
  205. const char* signature = (flags == O_RDONLY) ?
  206. JMETHOD2(JPARAM(HADOOP_PATH), "I", JPARAM(HADOOP_ISTRM)) :
  207. JMETHOD2(JPARAM(HADOOP_PATH), "ZISJ", JPARAM(HADOOP_OSTRM));
  208. /* Return value */
  209. hdfsFile file = NULL;
  210. /* Create an object of org.apache.hadoop.fs.Path */
  211. jobject jPath = constructNewObjectOfPath(env, path);
  212. if (jPath == NULL) {
  213. return NULL;
  214. }
  215. /* Get the Configuration object from the FileSystem object */
  216. jvalue jVal;
  217. jobject jConfiguration = NULL;
  218. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  219. "getConf", JMETHOD1("", JPARAM(HADOOP_CONF))) != 0) {
  220. fprintf(stderr, "Failed to get configuration object from "
  221. "filesystem\n");
  222. errno = EINTERNAL;
  223. destroyLocalReference(env, jPath);
  224. return NULL;
  225. }
  226. jConfiguration = jVal.l;
  227. jint jBufferSize = bufferSize;
  228. jshort jReplication = replication;
  229. jlong jBlockSize = blockSize;
  230. jstring jStrBufferSize = (*env)->NewStringUTF(env, "io.file.buffer.size");
  231. jstring jStrReplication = (*env)->NewStringUTF(env, "dfs.replication");
  232. jstring jStrBlockSize = (*env)->NewStringUTF(env, "dfs.block.size");
  233. //bufferSize
  234. if (!bufferSize) {
  235. if (invokeMethod(env, &jVal, INSTANCE, jConfiguration,
  236. HADOOP_CONF, "getInt", "(Ljava/lang/String;I)I",
  237. jStrBufferSize, 4096) != 0) {
  238. fprintf(stderr, "Call to org.apache.hadoop.conf."
  239. "Configuration::getInt failed!\n");
  240. errno = EINTERNAL;
  241. goto done;
  242. }
  243. jBufferSize = jVal.i;
  244. }
  245. if (flags == O_WRONLY) {
  246. //replication
  247. if (!replication) {
  248. if (invokeMethod(env, &jVal, INSTANCE, jConfiguration,
  249. HADOOP_CONF, "getInt", "(Ljava/lang/String;I)I",
  250. jStrReplication, 1) != 0) {
  251. fprintf(stderr, "Call to org.apache.hadoop.conf."
  252. "Configuration::getInt failed!\n");
  253. errno = EINTERNAL;
  254. goto done;
  255. }
  256. jReplication = jVal.i;
  257. }
  258. //blockSize
  259. if (!blockSize) {
  260. if (invokeMethod(env, &jVal, INSTANCE, jConfiguration,
  261. HADOOP_CONF, "getLong", "(Ljava/lang/String;J)J",
  262. jStrBlockSize, 67108864)) {
  263. fprintf(stderr, "Call to org.apache.hadoop.fs."
  264. "FileSystem::%s(%s) failed!\n", method, signature);
  265. errno = EINTERNAL;
  266. goto done;
  267. }
  268. jBlockSize = jVal.j;
  269. }
  270. }
  271. /* Create and return either the FSDataInputStream or
  272. FSDataOutputStream references jobject jStream */
  273. if (flags == O_RDONLY) {
  274. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  275. method, signature, jPath, jBufferSize)) {
  276. fprintf(stderr, "Call to org.apache.hadoop.fs."
  277. "FileSystem::%s(%s) failed!\n", method, signature);
  278. errno = EINTERNAL;
  279. goto done;
  280. }
  281. }
  282. else {
  283. jboolean jOverWrite = 1;
  284. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  285. method, signature, jPath, jOverWrite,
  286. jBufferSize, jReplication, jBlockSize)) {
  287. fprintf(stderr, "Call to org.apache.hadoop.fs."
  288. "FileSystem::%s(%s) failed!\n", method, signature);
  289. errno = EINTERNAL;
  290. goto done;
  291. }
  292. }
  293. file = malloc(sizeof(struct hdfsFile_internal));
  294. if (!file) {
  295. errno = ENOMEM;
  296. return NULL;
  297. }
  298. file->file = (*env)->NewGlobalRef(env, jVal.l);
  299. file->type = ((flags == O_RDONLY) ? INPUT : OUTPUT);
  300. destroyLocalReference(env, jVal.l);
  301. done:
  302. //Delete unnecessary local references
  303. destroyLocalReference(env, jStrBufferSize);
  304. destroyLocalReference(env, jStrReplication);
  305. destroyLocalReference(env, jStrBlockSize);
  306. destroyLocalReference(env, jConfiguration);
  307. destroyLocalReference(env, jPath);
  308. return file;
  309. }
  310. int hdfsCloseFile(hdfsFS fs, hdfsFile file)
  311. {
  312. // JAVA EQUIVALENT:
  313. // file.close
  314. //Get the JNIEnv* corresponding to current thread
  315. JNIEnv* env = getJNIEnv();
  316. //Parameters
  317. jobject jStream = (jobject)(file ? file->file : NULL);
  318. //Sanity check
  319. if (!file || file->type == UNINITIALIZED) {
  320. errno = EBADF;
  321. return -1;
  322. }
  323. //The interface whose 'close' method to be called
  324. const char* interface = (file->type == INPUT) ?
  325. HADOOP_ISTRM : HADOOP_OSTRM;
  326. if (invokeMethod(env, NULL, INSTANCE, jStream, interface,
  327. "close", "()V") != 0) {
  328. fprintf(stderr, "Call to %s::close failed!\n", interface);
  329. errno = EINTERNAL;
  330. return -1;
  331. }
  332. //De-allocate memory
  333. free(file);
  334. (*env)->DeleteGlobalRef(env, jStream);
  335. return 0;
  336. }
  337. int hdfsExists(hdfsFS fs, const char *path)
  338. {
  339. JNIEnv *env = getJNIEnv();
  340. jobject jPath = constructNewObjectOfPath(env, path);
  341. jvalue jVal;
  342. jobject jFS = (jobject)fs;
  343. if (jPath == NULL) {
  344. return -1;
  345. }
  346. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  347. "exists", JMETHOD1(JPARAM(HADOOP_PATH), "Z"),
  348. jPath) != 0) {
  349. fprintf(stderr, "Call to org.apache.hadoop.fs."
  350. "FileSystem::exists failed!\n");
  351. errno = EINTERNAL;
  352. return -1;
  353. }
  354. return jVal.z ? 0 : -1;
  355. }
  356. tSize hdfsRead(hdfsFS fs, hdfsFile f, void* buffer, tSize length)
  357. {
  358. // JAVA EQUIVALENT:
  359. // byte [] bR = new byte[length];
  360. // fis.read(bR);
  361. //Get the JNIEnv* corresponding to current thread
  362. JNIEnv* env = getJNIEnv();
  363. //Parameters
  364. jobject jInputStream = (jobject)(f ? f->file : NULL);
  365. jbyteArray jbRarray;
  366. jint noReadBytes = 0;
  367. jvalue jVal;
  368. //Sanity check
  369. if (!f || f->type == UNINITIALIZED) {
  370. errno = EBADF;
  371. return -1;
  372. }
  373. //Error checking... make sure that this file is 'readable'
  374. if (f->type != INPUT) {
  375. fprintf(stderr, "Cannot read from a non-InputStream object!\n");
  376. errno = EINVAL;
  377. return -1;
  378. }
  379. //Read the requisite bytes
  380. jbRarray = (*env)->NewByteArray(env, length);
  381. if (invokeMethod(env, &jVal, INSTANCE, jInputStream, HADOOP_ISTRM,
  382. "read", "([B)I", jbRarray) != 0) {
  383. fprintf(stderr, "Call to org.apache.hadoop.fs."
  384. "FSDataInputStream::read failed!\n");
  385. errno = EINTERNAL;
  386. noReadBytes = -1;
  387. }
  388. else {
  389. noReadBytes = jVal.i;
  390. if (noReadBytes > 0) {
  391. (*env)->GetByteArrayRegion(env, jbRarray, 0, noReadBytes, buffer);
  392. }
  393. //This is a valid case: there aren't any bytes left to read!
  394. errno = 0;
  395. }
  396. destroyLocalReference(env, jbRarray);
  397. return noReadBytes;
  398. }
  399. tSize hdfsPread(hdfsFS fs, hdfsFile f, tOffset position,
  400. void* buffer, tSize length)
  401. {
  402. // JAVA EQUIVALENT:
  403. // byte [] bR = new byte[length];
  404. // fis.read(pos, bR, 0, length);
  405. //Get the JNIEnv* corresponding to current thread
  406. JNIEnv* env = getJNIEnv();
  407. //Parameters
  408. jobject jInputStream = (jobject)(f ? f->file : NULL);
  409. jbyteArray jbRarray;
  410. jint noReadBytes = 0;
  411. jvalue jVal;
  412. //Sanity check
  413. if (!f || f->type == UNINITIALIZED) {
  414. errno = EBADF;
  415. return -1;
  416. }
  417. //Error checking... make sure that this file is 'readable'
  418. if (f->type != INPUT) {
  419. fprintf(stderr, "Cannot read from a non-InputStream object!\n");
  420. errno = EINVAL;
  421. return -1;
  422. }
  423. //Read the requisite bytes
  424. jbRarray = (*env)->NewByteArray(env, length);
  425. if (invokeMethod(env, &jVal, INSTANCE, jInputStream, HADOOP_ISTRM,
  426. "read", "(J[BII)I", position, jbRarray, 0, length) != 0) {
  427. fprintf(stderr, "Call to org.apache.hadoop.fs."
  428. "FSDataInputStream::read failed!\n");
  429. errno = EINTERNAL;
  430. noReadBytes = -1;
  431. }
  432. else {
  433. noReadBytes = jVal.i;
  434. if (noReadBytes > 0) {
  435. (*env)->GetByteArrayRegion(env, jbRarray, 0, noReadBytes, buffer);
  436. }
  437. //This is a valid case: there aren't any bytes left to read!
  438. errno = 0;
  439. }
  440. destroyLocalReference(env, jbRarray);
  441. return noReadBytes;
  442. }
  443. tSize hdfsWrite(hdfsFS fs, hdfsFile f, const void* buffer, tSize length)
  444. {
  445. // JAVA EQUIVALENT
  446. // byte b[] = str.getBytes();
  447. // fso.write(b);
  448. //Get the JNIEnv* corresponding to current thread
  449. JNIEnv* env = getJNIEnv();
  450. //Parameters
  451. jobject jOutputStream = (jobject)(f ? f->file : 0);
  452. jbyteArray jbWarray;
  453. //Sanity check
  454. if (!f || f->type == UNINITIALIZED) {
  455. errno = EBADF;
  456. return -1;
  457. }
  458. if (length < 0) {
  459. errno = EINVAL;
  460. return -1;
  461. }
  462. //Error checking... make sure that this file is 'writable'
  463. if (f->type != OUTPUT) {
  464. fprintf(stderr, "Cannot write into a non-OutputStream object!\n");
  465. errno = EINVAL;
  466. return -1;
  467. }
  468. // 'length' equals 'zero' is a valid use-case according to Posix!
  469. if (length != 0) {
  470. //Write the requisite bytes into the file
  471. jbWarray = (*env)->NewByteArray(env, length);
  472. (*env)->SetByteArrayRegion(env, jbWarray, 0, length, buffer);
  473. if (invokeMethod(env, NULL, INSTANCE, jOutputStream,
  474. HADOOP_OSTRM, "write",
  475. "([B)V", jbWarray) != 0) {
  476. fprintf(stderr, "Call to org.apache.hadoop.fs."
  477. "FSDataOutputStream::write failed!\n");
  478. errno = EINTERNAL;
  479. length = -1;
  480. }
  481. destroyLocalReference(env, jbWarray);
  482. }
  483. //Return no. of bytes succesfully written (libc way)
  484. //i.e. 'length' itself! ;-)
  485. return length;
  486. }
  487. int hdfsSeek(hdfsFS fs, hdfsFile f, tOffset desiredPos)
  488. {
  489. // JAVA EQUIVALENT
  490. // fis.seek(pos);
  491. //Get the JNIEnv* corresponding to current thread
  492. JNIEnv* env = getJNIEnv();
  493. //Parameters
  494. jobject jInputStream = (jobject)(f ? f->file : 0);
  495. //Sanity check
  496. if (!f || f->type != INPUT) {
  497. errno = EBADF;
  498. return -1;
  499. }
  500. if (invokeMethod(env, NULL, INSTANCE, jInputStream, HADOOP_ISTRM,
  501. "seek", "(J)V", desiredPos) != 0) {
  502. fprintf(stderr, "Call to org.apache.hadoop.fs."
  503. "FSDataInputStream::seek failed!\n");
  504. errno = EINTERNAL;
  505. return -1;
  506. }
  507. return 0;
  508. }
  509. tOffset hdfsTell(hdfsFS fs, hdfsFile f)
  510. {
  511. // JAVA EQUIVALENT
  512. // pos = f.getPos();
  513. //Get the JNIEnv* corresponding to current thread
  514. JNIEnv* env = getJNIEnv();
  515. //Parameters
  516. jobject jStream = (jobject)(f ? f->file : 0);
  517. //Sanity check
  518. if (!f || f->type == UNINITIALIZED) {
  519. errno = EBADF;
  520. return -1;
  521. }
  522. const char* interface = (f->type == INPUT) ?
  523. HADOOP_ISTRM : HADOOP_OSTRM;
  524. jlong currentPos = -1;
  525. jvalue jVal;
  526. if (invokeMethod(env, &jVal, INSTANCE, jStream,
  527. interface, "getPos", "()J") != 0) {
  528. fprintf(stderr, "Call to org.apache.hadoop.fs."
  529. "FSDataInputStream::getPos failed!\n");
  530. errno = EINTERNAL;
  531. return -1;
  532. }
  533. currentPos = jVal.j;
  534. return (tOffset)currentPos;
  535. }
  536. int hdfsFlush(hdfsFS fs, hdfsFile f)
  537. {
  538. // JAVA EQUIVALENT
  539. // fos.flush();
  540. //Get the JNIEnv* corresponding to current thread
  541. JNIEnv* env = getJNIEnv();
  542. //Parameters
  543. jobject jOutputStream = (jobject)(f ? f->file : 0);
  544. //Sanity check
  545. if (!f || f->type != OUTPUT) {
  546. errno = EBADF;
  547. return -1;
  548. }
  549. if (invokeMethod(env, NULL, INSTANCE, jOutputStream,
  550. HADOOP_OSTRM, "flush", "()V") != 0) {
  551. fprintf(stderr, "Call to org.apache.hadoop.fs."
  552. "FSDataInputStream::flush failed!\n");
  553. errno = EINTERNAL;
  554. return -1;
  555. }
  556. return 0;
  557. }
  558. int hdfsAvailable(hdfsFS fs, hdfsFile f)
  559. {
  560. // JAVA EQUIVALENT
  561. // fis.available();
  562. //Get the JNIEnv* corresponding to current thread
  563. JNIEnv* env = getJNIEnv();
  564. //Parameters
  565. jobject jInputStream = (jobject)(f ? f->file : 0);
  566. //Sanity check
  567. if (!f || f->type != INPUT) {
  568. errno = EBADF;
  569. return -1;
  570. }
  571. jint available = -1;
  572. jvalue jVal;
  573. if (invokeMethod(env, &jVal, INSTANCE, jInputStream,
  574. HADOOP_ISTRM, "available", "()I") != 0) {
  575. fprintf(stderr, "Call to org.apache.hadoop.fs."
  576. "FSDataInputStream::available failed!\n");
  577. errno = EINTERNAL;
  578. return -1;
  579. }
  580. available = jVal.i;
  581. return available;
  582. }
  583. int hdfsCopy(hdfsFS srcFS, const char* src, hdfsFS dstFS, const char* dst)
  584. {
  585. //JAVA EQUIVALENT
  586. // FileUtil::copy(srcFS, srcPath, dstFS, dstPath,
  587. // deleteSource = false, conf)
  588. //Get the JNIEnv* corresponding to current thread
  589. JNIEnv* env = getJNIEnv();
  590. //Parameters
  591. jobject jSrcFS = (jobject)srcFS;
  592. jobject jDstFS = (jobject)dstFS;
  593. jobject jSrcPath = NULL;
  594. jobject jDstPath = NULL;
  595. jSrcPath = constructNewObjectOfPath(env, src);
  596. if (jSrcPath == NULL) {
  597. return -1;
  598. }
  599. jDstPath = constructNewObjectOfPath(env, dst);
  600. if (jDstPath == NULL) {
  601. destroyLocalReference(env, jSrcPath);
  602. return -1;
  603. }
  604. int retval = 0;
  605. //Create the org.apache.hadoop.conf.Configuration object
  606. jobject jConfiguration =
  607. constructNewObjectOfClass(env, HADOOP_CONF, "()V");
  608. if (jConfiguration == NULL) {
  609. fprintf(stderr, "Can't construct instance of class "
  610. "org.apache.hadoop.conf.Configuration\n");
  611. errno = EINTERNAL;
  612. destroyLocalReference(env, jSrcPath);
  613. destroyLocalReference(env, jDstPath);
  614. return -1;
  615. }
  616. //FileUtil::copy
  617. jboolean deleteSource = 0; //Only copy
  618. jvalue jVal;
  619. if (invokeMethod(env, &jVal, STATIC,
  620. NULL, "org/apache/hadoop/fs/FileUtil", "copy",
  621. "(Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;ZLorg/apache/hadoop/conf/Configuration;)Z",
  622. jSrcFS, jSrcPath, jDstFS, jDstPath, deleteSource,
  623. jConfiguration) != 0) {
  624. fprintf(stderr, "Call to org.apache.hadoop.fs."
  625. "FileUtil::copy failed!\n");
  626. errno = EINTERNAL;
  627. retval = -1;
  628. goto done;
  629. }
  630. done:
  631. //Delete unnecessary local references
  632. destroyLocalReference(env, jConfiguration);
  633. destroyLocalReference(env, jSrcPath);
  634. destroyLocalReference(env, jDstPath);
  635. return retval;
  636. }
  637. int hdfsMove(hdfsFS srcFS, const char* src, hdfsFS dstFS, const char* dst)
  638. {
  639. //JAVA EQUIVALENT
  640. // FileUtil::copy(srcFS, srcPath, dstFS, dstPath,
  641. // deleteSource = true, conf)
  642. //Get the JNIEnv* corresponding to current thread
  643. JNIEnv* env = getJNIEnv();
  644. //Parameters
  645. jobject jSrcFS = (jobject)srcFS;
  646. jobject jDstFS = (jobject)dstFS;
  647. jobject jSrcPath = NULL;
  648. jobject jDstPath = NULL;
  649. jSrcPath = constructNewObjectOfPath(env, src);
  650. if (jSrcPath == NULL) {
  651. return -1;
  652. }
  653. jDstPath = constructNewObjectOfPath(env, dst);
  654. if (jDstPath == NULL) {
  655. destroyLocalReference(env, jSrcPath);
  656. return -1;
  657. }
  658. int retval = 0;
  659. //Create the org.apache.hadoop.conf.Configuration object
  660. jobject jConfiguration =
  661. constructNewObjectOfClass(env, HADOOP_CONF, "()V");
  662. if (jConfiguration == NULL) {
  663. fprintf(stderr, "Can't construct instance of class "
  664. "org.apache.hadoop.conf.Configuration\n");
  665. errno = EINTERNAL;
  666. destroyLocalReference(env, jSrcPath);
  667. destroyLocalReference(env, jDstPath);
  668. return -1;
  669. }
  670. //FileUtil::copy
  671. jboolean deleteSource = 1; //Delete src after copy
  672. jvalue jVal;
  673. if (invokeMethod(env, &jVal, STATIC, NULL,
  674. "org/apache/hadoop/fs/FileUtil", "copy",
  675. "(Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;Lorg/apache/hadoop/fs/FileSystem;Lorg/apache/hadoop/fs/Path;ZLorg/apache/hadoop/conf/Configuration;)Z",
  676. jSrcFS, jSrcPath, jDstFS, jDstPath, deleteSource,
  677. jConfiguration) != 0) {
  678. fprintf(stderr, "Call to org.apache.hadoop.fs."
  679. "FileUtil::copy(move) failed!\n");
  680. errno = EINTERNAL;
  681. retval = -1;
  682. goto done;
  683. }
  684. done:
  685. //Delete unnecessary local references
  686. destroyLocalReference(env, jConfiguration);
  687. destroyLocalReference(env, jSrcPath);
  688. destroyLocalReference(env, jDstPath);
  689. return retval;
  690. }
  691. int hdfsDelete(hdfsFS fs, const char* path)
  692. {
  693. // JAVA EQUIVALENT:
  694. // File f = new File(path);
  695. // bool retval = fs.delete(f);
  696. //Get the JNIEnv* corresponding to current thread
  697. JNIEnv* env = getJNIEnv();
  698. jobject jFS = (jobject)fs;
  699. //Create an object of java.io.File
  700. jobject jPath = constructNewObjectOfPath(env, path);
  701. if (jPath == NULL) {
  702. return -1;
  703. }
  704. //Delete the file
  705. jvalue jVal;
  706. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  707. "delete", "(Lorg/apache/hadoop/fs/Path;)Z",
  708. jPath) != 0) {
  709. fprintf(stderr, "Call to org.apache.hadoop.fs."
  710. "FileSystem::delete failed!\n");
  711. errno = EINTERNAL;
  712. return -1;
  713. }
  714. //Delete unnecessary local references
  715. destroyLocalReference(env, jPath);
  716. return (jVal.z) ? 0 : -1;
  717. }
  718. int hdfsRename(hdfsFS fs, const char* oldPath, const char* newPath)
  719. {
  720. // JAVA EQUIVALENT:
  721. // Path old = new Path(oldPath);
  722. // Path new = new Path(newPath);
  723. // fs.rename(old, new);
  724. //Get the JNIEnv* corresponding to current thread
  725. JNIEnv* env = getJNIEnv();
  726. jobject jFS = (jobject)fs;
  727. //Create objects of org.apache.hadoop.fs.Path
  728. jobject jOldPath = NULL;
  729. jobject jNewPath = NULL;
  730. jOldPath = constructNewObjectOfPath(env, oldPath);
  731. if (jOldPath == NULL) {
  732. return -1;
  733. }
  734. jNewPath = constructNewObjectOfPath(env, newPath);
  735. if (jNewPath == NULL) {
  736. destroyLocalReference(env, jOldPath);
  737. return -1;
  738. }
  739. //Rename the file
  740. jvalue jVal;
  741. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS, "rename",
  742. JMETHOD2(JPARAM(HADOOP_PATH), JPARAM(HADOOP_PATH), "Z"),
  743. jOldPath, jNewPath) != 0) {
  744. fprintf(stderr, "Call to org.apache.hadoop.fs."
  745. "FileSystem::rename failed!\n");
  746. errno = EINTERNAL;
  747. return -1;
  748. }
  749. //Delete unnecessary local references
  750. destroyLocalReference(env, jOldPath);
  751. destroyLocalReference(env, jNewPath);
  752. return (jVal.z) ? 0 : -1;
  753. }
  754. char* hdfsGetWorkingDirectory(hdfsFS fs, char* buffer, size_t bufferSize)
  755. {
  756. // JAVA EQUIVALENT:
  757. // Path p = fs.getWorkingDirectory();
  758. // return p.toString()
  759. //Get the JNIEnv* corresponding to current thread
  760. JNIEnv* env = getJNIEnv();
  761. jobject jFS = (jobject)fs;
  762. jobject jPath = NULL;
  763. jvalue jVal;
  764. //FileSystem::getWorkingDirectory()
  765. if (invokeMethod(env, &jVal, INSTANCE, jFS,
  766. HADOOP_FS, "getWorkingDirectory",
  767. "()Lorg/apache/hadoop/fs/Path;") != 0 ||
  768. jVal.l == NULL) {
  769. fprintf(stderr, "Call to FileSystem::getWorkingDirectory failed!\n");
  770. errno = EINTERNAL;
  771. return NULL;
  772. }
  773. jPath = jVal.l;
  774. //Path::toString()
  775. jstring jPathString;
  776. if (invokeMethod(env, &jVal, INSTANCE, jPath,
  777. "org/apache/hadoop/fs/Path", "toString",
  778. "()Ljava/lang/String;") != 0) {
  779. fprintf(stderr, "Call to Path::toString failed!\n");
  780. errno = EINTERNAL;
  781. destroyLocalReference(env, jPath);
  782. return NULL;
  783. }
  784. jPathString = jVal.l;
  785. const char *jPathChars = (const char*)
  786. ((*env)->GetStringUTFChars(env, jPathString, NULL));
  787. //Copy to user-provided buffer
  788. strncpy(buffer, jPathChars, bufferSize);
  789. //Delete unnecessary local references
  790. (*env)->ReleaseStringUTFChars(env, jPathString, jPathChars);
  791. destroyLocalReference(env, jPathString);
  792. destroyLocalReference(env, jPath);
  793. return buffer;
  794. }
  795. int hdfsSetWorkingDirectory(hdfsFS fs, const char* path)
  796. {
  797. // JAVA EQUIVALENT:
  798. // fs.setWorkingDirectory(Path(path));
  799. //Get the JNIEnv* corresponding to current thread
  800. JNIEnv* env = getJNIEnv();
  801. jobject jFS = (jobject)fs;
  802. int retval = 0;
  803. //Create an object of org.apache.hadoop.fs.Path
  804. jobject jPath = constructNewObjectOfPath(env, path);
  805. if (jPath == NULL) {
  806. return -1;
  807. }
  808. //FileSystem::setWorkingDirectory()
  809. if (invokeMethod(env, NULL, INSTANCE, jFS, HADOOP_FS,
  810. "setWorkingDirectory",
  811. "(Lorg/apache/hadoop/fs/Path;)V", jPath) != 0) {
  812. fprintf(stderr, "Call to FileSystem::setWorkingDirectory failed!\n");
  813. errno = EINTERNAL;
  814. retval = -1;
  815. }
  816. //Delete unnecessary local references
  817. destroyLocalReference(env, jPath);
  818. return retval;
  819. }
  820. int hdfsCreateDirectory(hdfsFS fs, const char* path)
  821. {
  822. // JAVA EQUIVALENT:
  823. // fs.mkdirs(new Path(path));
  824. //Get the JNIEnv* corresponding to current thread
  825. JNIEnv* env = getJNIEnv();
  826. jobject jFS = (jobject)fs;
  827. //Create an object of org.apache.hadoop.fs.Path
  828. jobject jPath = constructNewObjectOfPath(env, path);
  829. if (jPath == NULL) {
  830. return -1;
  831. }
  832. //Create the directory
  833. jvalue jVal;
  834. jVal.z = 0;
  835. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  836. "mkdirs", "(Lorg/apache/hadoop/fs/Path;)Z",
  837. jPath) != 0) {
  838. fprintf(stderr, "Call to org.apache.hadoop.fs.FileSystem::"
  839. "mkdirs failed!\n");
  840. errno = EINTERNAL;
  841. goto done;
  842. }
  843. done:
  844. //Delete unnecessary local references
  845. destroyLocalReference(env, jPath);
  846. return (jVal.z) ? 0 : -1;
  847. }
  848. char***
  849. hdfsGetHosts(hdfsFS fs, const char* path, tOffset start, tOffset length)
  850. {
  851. // JAVA EQUIVALENT:
  852. // fs.getFileCacheHints(new Path(path), start, length);
  853. //Get the JNIEnv* corresponding to current thread
  854. JNIEnv* env = getJNIEnv();
  855. jobject jFS = (jobject)fs;
  856. //Create an object of org.apache.hadoop.fs.Path
  857. jobject jPath = constructNewObjectOfPath(env, path);
  858. if (jPath == NULL) {
  859. return NULL;
  860. }
  861. //org.apache.hadoop.fs.FileSystem::getFileCacheHints
  862. char*** blockHosts = NULL;
  863. jobjectArray jFileCacheHints;
  864. jvalue jVal;
  865. if (invokeMethod(env, &jVal, INSTANCE, jFS,
  866. HADOOP_FS, "getFileCacheHints",
  867. "(Lorg/apache/hadoop/fs/Path;JJ)[[Ljava/lang/String;",
  868. jPath, start, length) != 0) {
  869. fprintf(stderr, "Call to org.apache.hadoop.fs."
  870. "FileSystem::getFileCacheHints failed!\n");
  871. errno = EINTERNAL;
  872. destroyLocalReference(env, jPath);
  873. return NULL;
  874. }
  875. jFileCacheHints = jVal.l;
  876. //Figure out no of entries in jFileCacheHints
  877. //Allocate memory and add NULL at the end
  878. jsize jNumFileBlocks = (*env)->GetArrayLength(env, jFileCacheHints);
  879. blockHosts = malloc(sizeof(char**) * (jNumFileBlocks+1));
  880. if (blockHosts == NULL) {
  881. errno = ENOMEM;
  882. goto done;
  883. }
  884. blockHosts[jNumFileBlocks] = NULL;
  885. if (jNumFileBlocks == 0) {
  886. errno = 0;
  887. goto done;
  888. }
  889. //Now parse each block to get hostnames
  890. int i = 0;
  891. for (i=0; i < jNumFileBlocks; ++i) {
  892. jobjectArray jFileBlockHosts =
  893. (*env)->GetObjectArrayElement(env, jFileCacheHints, i);
  894. //Figure out no of entries in jFileCacheHints
  895. //Allocate memory and add NULL at the end
  896. jsize jNumBlockHosts = (*env)->GetArrayLength(env, jFileBlockHosts);
  897. blockHosts[i] = malloc(sizeof(char*) * (jNumBlockHosts+1));
  898. if (blockHosts[i] == NULL) {
  899. int x = 0;
  900. for (x=0; x < i; ++x) {
  901. free(blockHosts[x]);
  902. }
  903. free(blockHosts);
  904. errno = ENOMEM;
  905. goto done;
  906. }
  907. blockHosts[i][jNumBlockHosts] = NULL;
  908. //Now parse each hostname
  909. int j = 0;
  910. const char *hostName;
  911. for (j=0; j < jNumBlockHosts; ++j) {
  912. jstring jHost =
  913. (*env)->GetObjectArrayElement(env, jFileBlockHosts, j);
  914. hostName =
  915. (const char*)((*env)->GetStringUTFChars(env, jHost, NULL));
  916. blockHosts[i][j] = strdup(hostName);
  917. (*env)->ReleaseStringUTFChars(env, jHost, hostName);
  918. destroyLocalReference(env, jHost);
  919. }
  920. destroyLocalReference(env, jFileBlockHosts);
  921. }
  922. done:
  923. //Delete unnecessary local references
  924. destroyLocalReference(env, jPath);
  925. destroyLocalReference(env, jFileCacheHints);
  926. return blockHosts;
  927. }
  928. void hdfsFreeHosts(char ***blockHosts)
  929. {
  930. int i, j;
  931. for (i=0; blockHosts[i]; i++) {
  932. for (j=0; blockHosts[i][j]; j++) {
  933. free(blockHosts[i][j]);
  934. }
  935. free(blockHosts[i]);
  936. }
  937. free(blockHosts);
  938. }
  939. tOffset hdfsGetDefaultBlockSize(hdfsFS fs)
  940. {
  941. // JAVA EQUIVALENT:
  942. // fs.getDefaultBlockSize();
  943. //Get the JNIEnv* corresponding to current thread
  944. JNIEnv* env = getJNIEnv();
  945. jobject jFS = (jobject)fs;
  946. //FileSystem::getDefaultBlockSize()
  947. tOffset blockSize = -1;
  948. jvalue jVal;
  949. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  950. "getDefaultBlockSize", "()J") != 0) {
  951. fprintf(stderr, "Call to org.apache.hadoop.fs."
  952. "FileSystem::getDefaultBlockSize failed!\n");
  953. errno = EINTERNAL;
  954. return -1;
  955. }
  956. blockSize = jVal.j;
  957. return blockSize;
  958. }
  959. tOffset hdfsGetCapacity(hdfsFS fs)
  960. {
  961. // JAVA EQUIVALENT:
  962. // fs.getRawCapacity();
  963. //Get the JNIEnv* corresponding to current thread
  964. JNIEnv* env = getJNIEnv();
  965. jobject jFS = (jobject)fs;
  966. if (!((*env)->IsInstanceOf(env, jFS,
  967. globalClassReference(HADOOP_DFS, env)))) {
  968. fprintf(stderr, "hdfsGetCapacity works only on a "
  969. "DistributedFileSystem!\n");
  970. return -1;
  971. }
  972. //FileSystem::getRawCapacity()
  973. jvalue jVal;
  974. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_DFS,
  975. "getRawCapacity", "()J") != 0) {
  976. fprintf(stderr, "Call to org.apache.hadoop.fs."
  977. "FileSystem::getRawCapacity failed!\n");
  978. errno = EINTERNAL;
  979. return -1;
  980. }
  981. return jVal.j;
  982. }
  983. tOffset hdfsGetUsed(hdfsFS fs)
  984. {
  985. // JAVA EQUIVALENT:
  986. // fs.getRawUsed();
  987. //Get the JNIEnv* corresponding to current thread
  988. JNIEnv* env = getJNIEnv();
  989. jobject jFS = (jobject)fs;
  990. if (!((*env)->IsInstanceOf(env, jFS,
  991. globalClassReference(HADOOP_DFS, env)))) {
  992. fprintf(stderr, "hdfsGetUsed works only on a "
  993. "DistributedFileSystem!\n");
  994. return -1;
  995. }
  996. //FileSystem::getRawUsed()
  997. jvalue jVal;
  998. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_DFS,
  999. "getRawUsed", "()J") != 0) {
  1000. fprintf(stderr, "Call to org.apache.hadoop.fs."
  1001. "FileSystem::getRawUsed failed!\n");
  1002. errno = EINTERNAL;
  1003. return -1;
  1004. }
  1005. return jVal.j;
  1006. }
  1007. static int
  1008. getFileInfo(JNIEnv *env, jobject jFS, jobject jPath, hdfsFileInfo *fileInfo)
  1009. {
  1010. // JAVA EQUIVALENT:
  1011. // fs.isDirectory(f)
  1012. // fs.lastModified() ??
  1013. // fs.getLength(f)
  1014. // f.getPath()
  1015. jboolean jIsDir;
  1016. jvalue jVal;
  1017. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  1018. "exists", JMETHOD1(JPARAM(HADOOP_PATH), "Z"),
  1019. jPath) != 0) {
  1020. fprintf(stderr, "Call to org.apache.hadoop.fs."
  1021. "FileSystem::exists failed!\n");
  1022. errno = EINTERNAL;
  1023. return -1;
  1024. }
  1025. if (jVal.z == 0) {
  1026. errno = EINTERNAL;
  1027. return -1;
  1028. }
  1029. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  1030. "isDirectory", "(Lorg/apache/hadoop/fs/Path;)Z",
  1031. jPath) != 0) {
  1032. fprintf(stderr, "Call to org.apache.hadoop.fs."
  1033. "FileSystem::isDirectory failed!\n");
  1034. errno = EINTERNAL;
  1035. return -1;
  1036. }
  1037. jIsDir = jVal.z;
  1038. /*
  1039. jlong jModTime = 0;
  1040. if (invokeMethod(env, (RetVal*)&jModTime, &jException, INSTANCE, jFS,
  1041. "org/apache/hadoop/fs/FileSystem", "lastModified",
  1042. "(Lorg/apache/hadoop/fs/Path;)J", jPath) != 0) {
  1043. fprintf(stderr,
  1044. "Call to org.apache.hadoop.fs.FileSystem::lastModified failed!\n"
  1045. );
  1046. errno = EINTERNAL;
  1047. return -1;
  1048. }
  1049. */
  1050. jlong jFileLength = 0;
  1051. if (!jIsDir) {
  1052. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS,
  1053. "getLength", "(Lorg/apache/hadoop/fs/Path;)J",
  1054. jPath) != 0) {
  1055. fprintf(stderr, "Call to org.apache.hadoop.fs."
  1056. "FileSystem::getLength failed!\n");
  1057. errno = EINTERNAL;
  1058. return -1;
  1059. }
  1060. jFileLength = jVal.j;
  1061. }
  1062. jstring jPathName;
  1063. if (invokeMethod(env, &jVal, INSTANCE, jPath, HADOOP_PATH,
  1064. "toString", "()Ljava/lang/String;")) {
  1065. fprintf(stderr, "Call to org.apache.hadoop.fs."
  1066. "Path::toString failed!\n");
  1067. errno = EINTERNAL;
  1068. return -1;
  1069. }
  1070. jPathName = jVal.l;
  1071. fileInfo->mKind = (jIsDir ? kObjectKindDirectory : kObjectKindFile);
  1072. //fileInfo->mCreationTime = jModTime;
  1073. fileInfo->mSize = jFileLength;
  1074. const char* cPathName = (const char*)
  1075. ((*env)->GetStringUTFChars(env, jPathName, NULL));
  1076. fileInfo->mName = strdup(cPathName);
  1077. (*env)->ReleaseStringUTFChars(env, jPathName, cPathName);
  1078. destroyLocalReference(env, jPathName);
  1079. return 0;
  1080. }
  1081. hdfsFileInfo* hdfsListDirectory(hdfsFS fs, const char* path, int *numEntries)
  1082. {
  1083. // JAVA EQUIVALENT:
  1084. // Path p(path);
  1085. // Path []pathList = fs.listPaths(p)
  1086. // foreach path in pathList
  1087. // getFileInfo(path)
  1088. //Get the JNIEnv* corresponding to current thread
  1089. JNIEnv* env = getJNIEnv();
  1090. jobject jFS = (jobject)fs;
  1091. //Create an object of org.apache.hadoop.fs.Path
  1092. jobject jPath = constructNewObjectOfPath(env, path);
  1093. if (jPath == NULL) {
  1094. return NULL;
  1095. }
  1096. hdfsFileInfo *pathList = 0;
  1097. jobjectArray jPathList = NULL;
  1098. jvalue jVal;
  1099. if (invokeMethod(env, &jVal, INSTANCE, jFS, HADOOP_FS, "listPaths",
  1100. JMETHOD1(JPARAM(HADOOP_PATH), JARRPARAM(HADOOP_PATH)),
  1101. jPath) != 0) {
  1102. fprintf(stderr, "Call to org.apache.hadoop.fs."
  1103. "FileSystem::listPaths failed!\n");
  1104. errno = EINTERNAL;
  1105. destroyLocalReference(env, jPath);
  1106. return NULL;
  1107. }
  1108. jPathList = jVal.l;
  1109. //Figure out no of entries in that directory
  1110. jsize jPathListSize = (*env)->GetArrayLength(env, jPathList);
  1111. *numEntries = jPathListSize;
  1112. if (jPathListSize == 0) {
  1113. errno = 0;
  1114. goto done;
  1115. }
  1116. //Allocate memory
  1117. pathList = calloc(jPathListSize, sizeof(hdfsFileInfo));
  1118. if (pathList == NULL) {
  1119. errno = ENOMEM;
  1120. goto done;
  1121. }
  1122. //Save path information in pathList
  1123. jsize i;
  1124. jobject tmpPath;
  1125. for (i=0; i < jPathListSize; ++i) {
  1126. tmpPath = (*env)->GetObjectArrayElement(env, jPathList, i);
  1127. if (getFileInfo(env, jFS, tmpPath, &pathList[i])) {
  1128. errno = EINTERNAL;
  1129. hdfsFreeFileInfo(pathList, jPathListSize);
  1130. destroyLocalReference(env, tmpPath);
  1131. pathList = NULL;
  1132. goto done;
  1133. }
  1134. destroyLocalReference(env, tmpPath);
  1135. }
  1136. done:
  1137. //Delete unnecessary local references
  1138. destroyLocalReference(env, jPath);
  1139. destroyLocalReference(env, jPathList);
  1140. return pathList;
  1141. }
  1142. hdfsFileInfo *hdfsGetPathInfo(hdfsFS fs, const char* path)
  1143. {
  1144. // JAVA EQUIVALENT:
  1145. // File f(path);
  1146. // fs.isDirectory(f)
  1147. // fs.lastModified() ??
  1148. // fs.getLength(f)
  1149. // f.getPath()
  1150. //Get the JNIEnv* corresponding to current thread
  1151. JNIEnv* env = getJNIEnv();
  1152. jobject jFS = (jobject)fs;
  1153. //Create an object of org.apache.hadoop.fs.Path
  1154. jobject jPath = constructNewObjectOfPath(env, path);
  1155. if (jPath == NULL) {
  1156. return NULL;
  1157. }
  1158. hdfsFileInfo *fileInfo = calloc(1, sizeof(hdfsFileInfo));
  1159. if (getFileInfo(env, jFS, jPath, fileInfo)) {
  1160. hdfsFreeFileInfo(fileInfo, 1);
  1161. fileInfo = NULL;
  1162. goto done;
  1163. }
  1164. done:
  1165. //Delete unnecessary local references
  1166. destroyLocalReference(env, jPath);
  1167. return fileInfo;
  1168. }
  1169. void hdfsFreeFileInfo(hdfsFileInfo *hdfsFileInfo, int numEntries)
  1170. {
  1171. //Free the mName
  1172. int i;
  1173. for (i=0; i < numEntries; ++i) {
  1174. if (hdfsFileInfo[i].mName) {
  1175. free(hdfsFileInfo[i].mName);
  1176. }
  1177. }
  1178. //Free entire block
  1179. free(hdfsFileInfo);
  1180. }
  1181. /**
  1182. * vim: ts=4: sw=4: et:
  1183. */