Updated fastbuf to use it.
Removed sh_foff_t -- all modules should use sh_off_t instead (the only
case where it would differ is the 2G--4G range of file sizes you get
when LFS is turned on and LARGE_DB turned off and it's not interesting
anyway)
bgeto/bgetp selection is done in config.h.
LFS is turned on by default.
/* Features */
-#undef SHERLOCK_CONFIG_LARGE_DB /* Support for DB files >4GB */
-#undef SHERLOCK_CONFIG_LFS /* Large files on 32-bit systems */
-#undef SHERLOCK_CONFIG_LFS_LIBC /* LFS supported directly by libc */
+#define SHERLOCK_CONFIG_LARGE_DB /* Support for DB files >4GB */
+#define SHERLOCK_CONFIG_LFS /* Large files on 32-bit systems */
+#define SHERLOCK_CONFIG_LFS_LIBC /* LFS supported directly by libc */
+
+/* CPU characteristics */
+
+#define CPU_LITTLE_ENDIAN
+#undef CPU_BIG_ENDIAN
+#define CPU_ALLOW_UNALIGNED
+#define CPU_STRUCT_ALIGN 4
/* Paths */
typedef u32 oid_t; /* Object ID */
-#ifdef SHERLOCK_CONFIG_LFS /* off_t as passed to file functions */
-typedef s64 sh_off_t;
-#define BYTES_PER_FILE_POINTER 5
-#else
-typedef int sh_off_t;
-#define BYTES_PER_FILE_POINTER 4
-#endif
+/* Data types and functions for accessing file positions */
-#ifdef SHERLOCK_CONFIG_LARGE_DB /* off_t as present in database files */
-typedef s64 sh_foff_t;
+#ifdef SHERLOCK_CONFIG_LARGE_DB
+typedef s64 sh_off_t;
+#define BYTES_PER_O 5
+#define BYTES_PER_P 8
+#define bgeto(f) bget5(f)
+#define bputo(f,l) bput5(f,l)
+#define bgetp(f) bgetq(f)
+#define bputp(f,l) bputq(f,l)
+#define GET_O(p) GET_U40(p)
+#define GET_P(p) GET_U64(p)
#else
-typedef s32 sh_foff_t;
+typedef s32 sh_off_t;
+#define BYTES_PER_O 4
+#define BYTES_PER_P 4
+#define bgeto(f) bgetl(f)
+#define bputo(f,l) bputl(f,l)
+#define bgetp(f) bgetl(f)
+#define bputp(f,l) bputl(f,l)
+#define GET_O(p) GET_U32(p)
+#define GET_P(p) GET_U32(p)
#endif
-/* CPU characteristics */
-
-#define CPU_LITTLE_ENDIAN
-#undef CPU_BIG_ENDIAN
-#define CPU_CAN_DO_UNALIGNED_WORDS
-#define CPU_CAN_DO_UNALIGNED_LONGS
-#define CPU_STRUCT_ALIGN 4
-
/* Misc */
#ifdef __GNUC__
#include <stdio.h>
#endif
+#include "lib/unaligned.h"
+
/*
* Generic buffered I/O on a top of buffer swapping functions.
*
word w;
if (f->bptr + 2 <= f->bstop)
{
- byte *p = f->bptr;
-#ifdef CPU_CAN_DO_UNALIGNED_WORDS
- w = * ((word *) p);
-#else
-#ifdef CPU_BIG_ENDIAN
- w = (p[0] << 8) | p[1];
-#else
- w = (p[1] << 8) | p[0];
-#endif
-#endif
+ w = GET_U16(f->bptr);
f->bptr += 2;
return w;
}
u32 l;
if (f->bptr + 4 <= f->bstop)
{
- byte *p = f->bptr;
-#ifdef CPU_CAN_DO_UNALIGNED_LONGS
- l = * ((u32 *) p);
-#else
-#ifdef CPU_BIG_ENDIAN
- l = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-#else
- l = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
-#endif
-#endif
+ l = GET_U32(f->bptr);
f->bptr += 4;
return l;
}
u64 bgetq_slow(struct fastbuf *f);
static inline u64 bgetq(struct fastbuf *f)
{
+ u64 l;
if (f->bptr + 8 <= f->bstop)
{
- u64 l;
- memcpy(&l, f->bptr, 8);
+ l = GET_U64(f->bptr);
f->bptr += 8;
return l;
}
u64 l;
if (f->bptr + 5 <= f->bstop)
{
- byte *p = f->bptr;
-#ifdef CPU_BIG_ENDIAN
- l = ((u64)p[0] << 32) | (u32)((p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]);
-#else
- l = ((u64)p[4] << 32) | (u32)((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
-#endif
+ l = GET_U40(f->bptr);
f->bptr += 5;
return l;
}
{
if (f->bptr + 2 <= f->bufend)
{
- byte *p = f->bptr;
-#ifdef CPU_CAN_DO_UNALIGNED_WORDS
- * ((word *) p) = w;
-#else
-#ifdef CPU_BIG_ENDIAN
- p[0] = w >> 8U;
- p[1] = w;
-#else
- p[1] = w >> 8U;
- p[0] = w;
-#endif
-#endif
+ PUT_U16(f->bptr, w);
f->bptr += 2;
}
else
{
if (f->bptr + 4 <= f->bufend)
{
- byte *p = f->bptr;
-#ifdef CPU_CAN_DO_UNALIGNED_LONGS
- * ((u32 *) p) = l;
-#else
-#ifdef CPU_BIG_ENDIAN
- p[0] = l >> 24U;
- p[1] = l >> 16U;
- p[2] = l >> 8U;
- p[3] = l;
-#else
- p[3] = l >> 24U;
- p[2] = l >> 16U;
- p[1] = l >> 8U;
- p[0] = l;
-#endif
-#endif
+ PUT_U32(f->bptr, l);
f->bptr += 4;
}
else
{
if (f->bptr + 8 <= f->bufend)
{
- memcpy(f->bptr, &l, 8);
+ PUT_U64(f->bptr, l);
f->bptr += 8;
}
else
{
if (f->bptr + 5 <= f->bufend)
{
- byte *p = f->bptr;
- u32 low = l;
-#ifdef CPU_BIG_ENDIAN
- p[0] = l >> 32U;
- p[1] = low >> 24U;
- p[2] = low >> 16U;
- p[3] = low >> 8U;
- p[4] = low;
-#else
- p[4] = l >> 32U;
- p[3] = low >> 24U;
- p[2] = low >> 16U;
- p[1] = low >> 8U;
- p[0] = low;
-#endif
+ PUT_U40(f->bptr, l);
f->bptr += 5;
}
else
int bdirect_write_prepare(struct fastbuf *f, byte **buf);
void bdirect_write_commit(struct fastbuf *f, byte *pos);
-/* Depending on compile-time configuration, we select the right function for reading/writing of file offsets */
-
-#ifdef SHERLOCK_CONFIG_LARGE_DB
-#define bgeto(f) bget5(f)
-#define bputo(f,l) bput5(f,l)
-#define bgetp(f) bgetq(f)
-#define bputp(f,l) bputq(f,l)
-#define FASTBUF_BYTES_PER_O 5
-#define FASTBUF_BYTES_PER_P 8
-#else
-#define bgeto(f) bgetl(f)
-#define bputo(f,l) bputl(f,l)
-#define bgetp(f) bgetl(f)
-#define bputp(f,l) bputl(f,l)
-#define FASTBUF_BYTES_PER_O 4
-#define FASTBUF_BYTES_PER_P 4
-#endif
-
#endif
--- /dev/null
+/*
+ * Sherlock Library -- Fast Access to Unaligned Data
+ *
+ * (c) 1997--2001 Martin Mares <mj@ucw.cz>
+ */
+
+#ifndef _SHERLOCK_UNALIGNED_H
+#define _SHERLOCK_UNALIGNED_H
+
+#ifdef CPU_ALLOW_UNALIGNED
+#define GET_U16(p) (*((u16 *)(p)))
+#define GET_U32(p) (*((u32 *)(p)))
+#define GET_U64(p) (*((u64 *)(p)))
+#define PUT_U16(p,x) *((u16 *)(p)) = (x)
+#define PUT_U32(p,x) *((u32 *)(p)) = (x)
+#define PUT_U64(p,x) *((u64 *)(p)) = (x)
+#else
+#define GET_U64(p) ({ u64 _x; memcpy(&_x, p, 8); _x; })
+#define PUT_U64(p,x) do { u64 _x=x; memcpy(p, &_x, 8); } while(0)
+#ifdef CPU_BIG_ENDIAN
+#define GET_U16(p) (((p)[0] << 8) | (p)[1])
+#define GET_U32(p) (((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | (p)[3])
+#define PUT_U16(p,x) (void)(((p)[0] = ((x) >> 8)), (((p)[1]) = (x)))
+#define PUT_U32(p,x) (void)(((p)[0] = ((x) >> 24)), (((p)[1]) = ((x) >> 16)), (((p)[2]) = ((x) >> 8)), (((p)[3]) = (x)))
+#else
+#define GET_U16(p) (((p)[1] << 8) | (p)[0])
+#define GET_U32(p) (((p)[3] << 24) | ((p)[2] << 16) | ((p)[1] << 8) | (p)[0])
+#define PUT_U16(p,x) (void)(((p)[1] = ((x) >> 8)), (((p)[0]) = (x)))
+#define PUT_U32(p,x) (void)(((p)[3] = ((x) >> 24)), (((p)[2]) = ((x) >> 16)), (((p)[1]) = ((x) >> 8)), (((p)[0]) = (x)))
+#endif
+#endif
+
+#ifdef CPU_BIG_ENDIAN
+#define GET_U40(p) (((u64) (p)[0] << 32) | GET_U32((p)+1))
+#define PUT_U40(p,x) do { (p)[0] = ((x) >> 32); PUT_U32(((p)+1), x); } while(0)
+#else
+#define GET_U40(p) (((u64) (p)[4] << 32) | GET_U32(p))
+#define PUT_U40(p,x) do { (p)[4] = ((x) >> 32); PUT_U32(p, x); } while(0)
+#endif
+
+#endif