get.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*!
  2. \file rowio/get.c
  3. \brief RowIO library - Get a row
  4. (C) 2001-2009 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Original author CERL
  8. */
  9. #include <stdio.h>
  10. #include <grass/rowio.h>
  11. static void *my_select(ROWIO *, int);
  12. static void pageout(ROWIO *, int);
  13. /*!
  14. * \brief Read a row
  15. *
  16. * Rowio_get() returns a buffer which holds the data for row from the
  17. * file associated with ROWIO structure <i>R</i>. If the row requested
  18. * is not in memory, the getrow() routine specified in
  19. * Rowio_setup() is called to read row into memory and a
  20. * pointer to the memory buffer containing the row is returned. If the
  21. * data currently in the buffer had been changed by Rowio_put(),
  22. * the putrow() routine specified in Rowio_setup() is
  23. * called first to write the changed row to disk. If row is
  24. * already in memory, no disk read is done. The pointer to the data is
  25. * simply returned.
  26. *
  27. * \param R pointer to ROWIO structure
  28. * \param row row number
  29. *
  30. * \return NULL on error
  31. * \return pointer to the buffer containing row
  32. */
  33. void *Rowio_get(ROWIO * R, int row)
  34. {
  35. int i;
  36. int age;
  37. int cur;
  38. if (row < 0)
  39. return NULL;
  40. if (row == R->cur)
  41. return R->buf;
  42. for (i = 0; i < R->nrows; i++)
  43. if (row == R->rcb[i].row)
  44. return my_select(R, i);
  45. age = 0;
  46. cur = 0;
  47. for (i = 0; i < R->nrows; i++)
  48. if (R->rcb[i].row < 0) { /* free slot ! */
  49. cur = i;
  50. break;
  51. }
  52. else if (age < R->rcb[i].age) {
  53. cur = i;
  54. age = R->rcb[i].age;
  55. }
  56. pageout(R, cur);
  57. i = (*R->getrow) (R->fd, R->rcb[cur].buf, R->rcb[cur].row = row, R->len);
  58. R->rcb[cur].dirty = 0;
  59. if (!i) {
  60. R->rcb[cur].row = -1;
  61. if (cur == R->cur)
  62. R->cur = -1;
  63. return NULL;
  64. }
  65. return my_select(R, cur);
  66. }
  67. /*!
  68. \brief Flush data
  69. \param R pointer to ROWIO strcuture
  70. */
  71. void Rowio_flush(ROWIO * R)
  72. {
  73. int i;
  74. for (i = 0; i < R->nrows; i++)
  75. pageout(R, i);
  76. }
  77. static void pageout(ROWIO * R, int cur)
  78. {
  79. if (R->rcb[cur].row < 0)
  80. return;
  81. if (!R->rcb[cur].dirty)
  82. return;
  83. (*R->putrow) (R->fd, R->rcb[cur].buf, R->rcb[cur].row, R->len);
  84. R->rcb[cur].dirty = 0;
  85. }
  86. static void *my_select(ROWIO * R, int n)
  87. {
  88. int i;
  89. R->rcb[n].age = 0;
  90. for (i = 0; i < R->nrows; i++)
  91. R->rcb[i].age++;
  92. R->cur = R->rcb[n].row;
  93. R->buf = R->rcb[n].buf;
  94. return R->buf;
  95. }